skip to Main Content

I have a table with two divs inside a cell. I want the first div aligned to the top of the cell, and the last div aligned to the bottom. This is an example of what the table might look like:

<table>
  <tr>
    <td class="left-cell">
      <div class="cell-container">
        <div class="first-div">
          This content should be at top of the cell, but not overlap
        </div>
        <div class="last-div">
          This content should be at bottom of the cell, but not overlap
        </div>
      </div>
    </td>
    <td>
      Long Content
      <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    </td>
  </tr>
  
  <tr>
    <td class="left-cell">
      <div class="cell-container">
        <div class="first-div">
          This content should be at top of the cell, but not overlap
        </div>
        <div class="last-div">
          This content should be at bottom of the cell, but not overlap
        </div>
      </div>
    </td>
    <td>
      Shorter Content
    </td>
  </tr>
</table>

My first attempt was to use relative positioning on the table cell, and absolute positioning on the bottom div. This works when the table cell is tall enough to fit all the content, but the absolute positioning causes the two divs to overlap for smaller cells.

CodePen: https://codepen.io/Adam-Petersen/pen/mdgJwaG

Next I tried to use Flexbox, but it appears there is some non-trivial rendering logic when using Flexbox inside of a table cell. This is the best attempt I have come up with so far:

CodePen: https://codepen.io/Adam-Petersen/pen/NWmqgeZ

This works perfectly in Chrome, but doesn’t work in Firefox. I don’t understand why the height: 0px is required on the td for it to actually justify the content how I want in Chrome, but without working in Firefox I will have to come up with something else.

Is there some way to make this CSS compatible with Firefox, or is there another approach entirely that I’m not considering?

2

Answers


  1. Just in case you are not stuck on table markup you can use a grid with more flexible style capability.

    .table-container {
      height: 100vh;
      display: grid;
      grid-template-rows: 1fr;
    }
    
    .table-container>* {
      padding: 1em;
    }
    
    .row-thing {
      display: grid;
      grid-template-columns: auto 1fr;
      grid-template-rows: 1fr;
      border: solid red 1px;
      padding: 0.25em;
    }
    
    .left-cell {
      padding: 1em;
      background-color: #00ffff10;
    }
    
    .cell-container {
      height: 100%;
      display: grid;
      grid-template-rows: 1fr auto;
      align-items: space-between;
      border: solid 1px blue;
    }
    
    .first-div {
      align-self: start;
    }
    
    .last-div {
      align-self: end;
    }
    <div class="table-container">
      <div class="row-thing">
        <div class="left-cell">
          <div class="cell-container">
            <div class="first-div">
              This content should be at top of the cell, but not overlap
            </div>
            <div class="last-div">
              This content should be at bottom of the cell, but not overlap
            </div>
          </div>
        </div>
        <div>
          Long Content
          <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
        </div>
      </div>
    
      <div class="row-thing">
        <div class="left-cell">
          <div class="cell-container">
            <div class="first-div">
              This content should be at top of the cell, but not overlap
            </div>
            <div class="last-div">
              This content should be at bottom of the cell, but not overlap
            </div>
          </div>
        </div>
        <div>
          Shorter Content
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. It is kind of hacky but setting table,td {height: 100%;} works.

    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      height: 100%;
    }
    
    .left-cell {
      width: 300px;
    }
    
    .cell-container {
      height: 100%;
      display: flex;
      flex-flow: column wrap;
      justify-content: space-between;
    }
    <table>
      <tr>
        <td class="left-cell">
          <div class="cell-container">
            <div class="first-div">
              This content should be at top of the cell, but not overlap
            </div>
            <div class="last-div">
              This content should be at bottom of the cell, but not overlap
            </div>
          </div>
        </td>
        <td>
          Long Content
          <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>...
        </td>
      </tr>
      <tr>
        <td class="left-cell">
          <div class="cell-container">
            <div class="first-div">
              This content should be at top of the cell, but not overlap
            </div>
            <div class="last-div">
              This content should be at bottom of the cell, but not overlap
            </div>
          </div>
        </td>
        <td>
          Shorter Content
        </td>
      </tr>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search