Mithun Shreevatsa
Mithun Shreevatsa

Reputation: 3629

How to align a span or div to the middle when it's rotated?

I am trying to match with nested accordion layout based on just HTML and CSS to match with an mock up which looks exactly like below:

enter image description here

My implementation layout looks like this:

enter image description here

There are alignment issues to align center for rotated text and width issues in the design.

body{
    background: seagreen;
    font-size: 16px;
    font-family: Arial;
    color: #333;
    border-color: none;

  }
  div.container{
    margin: 0 auto;
    padding: 10px;
    background: #ccc;
    border: solid 1px;
    width: 50%;
  }
  li {
    list-style-type: none;
    padding: 5px;
    background: #ddd;
    border: solid 1px; 
  }
  li.has-children.and{
    background: #4059AA;
  }
  li.has-children.or {
    background: #BE60A6;    		
  }
  li.has-children ul {
    margin-top: -3%;
  }
  li span{
    display: inline-block;
    font-weight: bold;
    /* Safari */
    -webkit-transform: rotate(-90deg);
    vertical-align: baseline;
    /* Firefox */
    -moz-transform: rotate(-90deg);

    /* IE */
    -ms-transform: rotate(-90deg);

    /* Opera */
    -o-transform: rotate(-90deg);

    /* Internet Explorer */
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);

    /*-webkit-transform: skewY(3deg);
    -moz-transform: skewY(3deg);*/
      -webkit-transform-origin: bottom right;
      -moz-transform-origin: bottom right;
  }
<div class="container">
  <ul class="tabs">
    <li class="has-children and">
      <span>AND</span>
      <ul>
        <li>Sachin</li>
        <li>Sourav</li>
        <li>Dravid</li>
        <li class="has-children or">
          <span>OR</span>
          <ul>
            <li>Bravo</li>
            <li>Gayle</li>
            <li>Sarwan</li>
            <li class="has-children and">
              <span>AND</span>
              <ul>
                <li>Hansie</li>
                <li>Rhodes</li>
                <li>Pollock</li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>	
    </li>
  </ul>
</div>

Upvotes: 4

Views: 324

Answers (1)

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123438

My attempt:

Codepen demo

Some specs:

  • all the logical operators are data- attributes of the list and written as the content of a before pseudoelement of the lists
  • the vertical orientation works by the writing-mode: vertical-lr; property
  • the colours are defined with a CSS variable inline, but of course you could use a class instead
  • the data inside is placed as flexbox columns and you can control the vertical alignment of data and headers

The final result is quite responsive

Markup

<div class="data">
  <ul data-logical-operator="AND" style="--bg:blue">
    <li> <!-- 1st level -->
      <dl>
        <dt><span>Attribute</span></dt>
        <dd><span>LLDP System Description</span></dd>
        <dt><span>Operator</span></dt>
        <dd><span>Equal</span></dd>
        <dt><span>Value</span></dt>
        <dd><span>RegDN 6388 MINET_6920</span></dd>
      </dl>

      <ul data-logical-operator="OR" style="--bg:violet"> <!-- 2nd level -->
        <li>
          <dl>
            <dt><span>Attribute</span></dt>
            <dd><span>LLDP System Description</span></dd>
            <dt><span>Operator</span></dt>
            <dd><span>Equal</span></dd>
            <dt><span>Value</span></dt>
            <dd><span>RegDN 6388 MINET_6920</span></dd>
          </dl>      
          <dl>
            <dt><span>Attribute</span></dt>
            <dd><span>LLDP System Description</span></dd>
            <dt><span>Operator</span></dt>
            <dd><span>Equal</span></dd>
            <dt><span>Value</span></dt>
            <dd><span>RegDN 6388 MINET_6920</span></dd>
          </dl>

          <ul data-logical-operator="AND" style="--bg:blue">  <!-- 3rd level -->
            <li>
              <dl>
                <dt><span>Attribute</span></dt>
                <dd><span>LLDP System Description</span></dd>
                <dt><span>Operator</span></dt>
                <dd><span>Equal</span></dd>
                <dt><span>Value</span></dt>
                <dd><span>RegDN 6388 MINET_6920</span></dd>
              </dl>
            </li>
          </ul>  <!-- /3nd level -->

        </li>  
      </ul> <!-- /2nd level -->

    </li> <!-- /1st level -->  
  </ul>
</div>

CSS

.data { position: relative; font: 14px Arial;}
.data ul { 
  margin: 0; 
  position: relative;
  padding-left: 45px;
  list-style: none; }

.data dl {
  padding: 0 20px;
  margin: 0 0 15px 0;
  border: 1px #d8d8d8 solid;
  width: 100%;
  display: flex;
  height: 6rem;
  flex-flow: column wrap;
}

.data dt, .data dd {
  margin: 0;
  height: 50%;
  width: 30%;
  line-height: 3rem;
}


.data dl span { 
  line-height: 1.3; 
  display: inline-block; }

.data dt span { vertical-align: middle; }
.data dd span { vertical-align: top; }


.data ul[data-logical-operator]::before {
  display: inline-block;
  content: attr(data-logical-operator);
  background-color: var(--bg);
  color: #fff;
  position: absolute;
  width: 45px;
  bottom: 0;
  line-height: 45px;
  top: 0;
  text-align: center;
  transform: rotateZ(180deg);
  writing-mode: vertical-lr;
}

Result

enter image description here

Upvotes: 3

Related Questions