Align div Elements with content within table cell

Viewed 32

I am having problem aligning div elements in a table cell. Specially when the div element contains content in the CSS. It seems the div containing content drops below the other divs for a reason that I could not figure out, as shown in the image below. I have created a minimum example of the problem where I want the green div to align vertically with the other two divs inside the td element.

tr {
  height: 30px;
}

td {
  width: 100px
}

.l1 {
  height: 30px;
  width: 10px;
  background: blue;
  display: inline-block;
}

.l2 {
  height: 30px;
  width: 10px;
  background: red;
  display: inline-block;
}

.toggle {
  height: 30px;
  width: 20px;
  background: green;
  display: inline-block;
}

.toggle:before {
  content: "\229F";
}
<body>
  <div class="container">
    <table>
      <tr>
        <td class="level2">
          <div class="l1"></div>
          <div class="l2"></div>
          <div class="toggle"></div>
        </td>
        <td>Task 1</td>
      </tr>
    </table>
  </div>
</body>

5 Answers

Try adding vertical-align: top; to the .toggle class

tr {
  height: 30px;
}

td {
  width: 100px
}

.l1 {
  height: 30px;
  width: 10px;
  background: blue;
  display: inline-block;
}

.l2 {
  height: 30px;
  width: 10px;
  background: red;
  display: inline-block;
}

.toggle {
  height: 30px;
  width: 20px;
  background: green;
  display: inline-block;
  vertical-align: top;
}

.toggle:before {
  content: "\229F";
}
<body>
  <div class="container">
    <table>
      <tr>
        <td class="level2">
          <div class="l1"></div>
          <div class="l2"></div>
          <div class="toggle"></div>
        </td>
        <td>Task 1</td>
      </tr>
    </table>
  </div>
</body>

As you're already specifying display: inline-block; for the divs inside the td.level2 column, the easiest possible solution here is to use vertical-align: middle; to vertically center those divs.

Here's a live demo:

/** vertically center all the DIVs inside the column with class "level2" */
td.level2 > div {
  vertical-align: middle;
}

tr {
  height: 30px;
}

td {
  width: 100px
}

.l1 {
  height: 30px;
  width: 10px;
  background: blue;
  display: inline-block;
}

.l2 {
  height: 30px;
  width: 10px;
  background: red;
  display: inline-block;
}

.toggle {
  height: 30px;
  width: 20px;
  background: green;
  display: inline-block;
}

.toggle:before {
  content: "\229F";
}
<body>
  <div class="container">
    <table>
      <tr>
        <td class="level2">
          <div class="l1"></div>
          <div class="l2"></div>
          <div class="toggle"></div>
        </td>
        <td>Task 1</td>
      </tr>
    </table>
  </div>
</body>

Learn more about vertical-align rule on MDN.

The text content inside the green element has whitespace included, as all inline text content does. This extends outside the green element. You can change that with the overflow property.

tr {
  height: 30px;
}

td {
  width: 100px
}

.l1 {
  height: 30px;
  width: 10px;
  background: blue;
  display: inline-block;
}

.l2 {
  height: 30px;
  width: 10px;
  background: red;
  display: inline-block;
}

.toggle {
  height: 30px;
  width: 20px;
  background: green;
  display: inline-block;
  overflow: hidden; /* <------------ here */
}

.toggle:before {
  content: "\229F";
}
<body>
  <div class="container">
    <table>
      <tr>
        <td class="level2">
          <div class="l1"></div>
          <div class="l2"></div>
          <div class="toggle"></div>
        </td>
        <td>Task 1</td>
      </tr>
    </table>
  </div>
</body>

just add position: absolute to :before

tr {
  height: 30px;
}

td {
  width: 100px
}

.l1 {
  height: 30px;
  width: 10px;
  background: blue;
  display: inline-block;
}

.l2 {
  height: 30px;
  width: 10px;
  background: red;
  display: inline-block;
}

.toggle {
  height: 30px;
  width: 20px;
  background: green;
  display: inline-block;
}

.toggle:before {
  content: "\229F";
  position: absolute;
}
<body>
  <div class="container">
    <table>
      <tr>
        <td class="level2">
          <div class="l1"></div>
          <div class="l2"></div>
          <div class="toggle"></div>
        </td>
        <td>Task 1</td>
      </tr>
    </table>
  </div>
</body>

simply add the first two in a container then add display flex to level2 then set flex-direction to column

<div class="container">
  <div class="l1"></div>
  <div class="l2"></div>
</div>
<div class="toggle"></div>

.level2 {
   display: flex;
}

tr{
    height: 30px;
  
}

td{
    width: 100px;
 
}

.l1{
    height:30px;
    width:10px;
    background:blue;
    display:inline-block;
}

.l2{
    height:30px;
    width:10px;
    background:red;
    display:inline-block;
}

.level2 {
   display: flex;
   flex-direction: column;
}

.toggle{
    height:30px;
    width:20px;
    background:green;
    display:inline-block;
    
}


.toggle:before{
    content:"\229F";
}
<body>
        <div class="container">
            <table>
                <tr>
                    <td class="level2">
                        <div class="container">
                          <div class="l1"></div>
              <div class="l2"></div>
                        </div>
                        <div class="toggle"></div>
                    </td>
                    <td>Task 1</td>
                </tr>
            </table>
        </div>
    </body>

Related