Fixed height table with overflow-x for the cell content

Viewed 226

I want my table cells to have a fixed height of 62px, I tried many solutions but I couldn't achieve this, and the one below is the closest one.

The problem I have is that the text inside my table cell is not displayed correctly, it's partially hidden.

The content of the table cells is dynamic, and my desired behavior, is for the table cell to grow in width to fit its content, and then the table will have a horizontal scroll since the overall width of the table would surpass its wrapper.

I know that white-space: nowrap; would solve the text overflowing issue, but I want the text to go to the second line because there is enough space for it line-height of 24px * 2 < 62px < line-height of 24px * 3. So it will either have one line or two lines depending on the cell min-width, and it the width of the cell will grow to fit it's content without having more than two lines, since three lines will result in a height > 62px

As for this solution:

Have table cell grow horizontally when cell content is large

I can't use it, since the min-content property is not supported by IE11.

How can I solve this?

.container {
  width: 600px;
  overflow: scroll:
}

table {
  table-layout: fixed;
  min-width: 100%;
  overflow-x: auto;
}

tr>th:first-of-type,
tr>td:first-of-type {
  min-width: 70px;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
  min-width: 124px;
}

tbody td {
  color: #01216c;
  line-height: 24px;
  padding: 0 12px;
  height: 62px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
  overflow: hidden;
  min-width: 124px;
}

td>span {
  max-height: 62px;
  display: block;
}
<div class="container">

  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
    </tbody>
  </table>

</div>

5 Answers

I think this is not possible with pure css. But you can solve it with a small javascript. Increase the width of each table cell span until the height is small enough.

Working example:

var spans = document.querySelectorAll('td span');

for (i = 0; i < spans.length; i++) {
  const td_style = window.getComputedStyle(spans[i].parentNode);
  const span_style = window.getComputedStyle(spans[i]);
  const line_height = parseInt(td_style.getPropertyValue('line-height'));

  while (parseInt(span_style.getPropertyValue('height')) > line_height * 2) {
    spans[i].style.width = (parseInt(span_style.getPropertyValue('width')) + 5) + 'px';
  }
}
.container {
  width: 600px;
  overflow-x: auto;
}

table {
  min-width: 100%;
}

tr>th:first-of-type,
tr>td:first-of-type {
  min-width: 70px;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
  min-width: 124px;
}

tbody td {
  color: #01216c;
  line-height: 24px;
  padding: 0 12px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
}

td>span {
  display: block;
  max-height: 62px;
}
<div class="container">

  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
      </tr>
    </tbody>
  </table>

</div>

If you are using jQuery in your page you could simplify the script to:

$('td span').each(function() {
  const line_height = parseInt($(this).parent().css('line-height'));
  
  while ($(this).height() > line_height * 2) {
    $(this).css('width', '+=5');
  }
});

Working example:

$('td span').each(function() {
  const line_height = parseInt($(this).parent().css('line-height'));
  
  while ($(this).height() > line_height * 2) {
    $(this).css('width', '+=5');
  }
});
.container {
  width: 600px;
  overflow-x: auto;
}

table {
  min-width: 100%;
}

tr>th:first-of-type,
tr>td:first-of-type {
  min-width: 70px;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
  min-width: 124px;
}

tbody td {
  color: #01216c;
  line-height: 24px;
  padding: 0 12px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
}

td>span {
  display: block;
  max-height: 62px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">

  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
      </tr>
    </tbody>
  </table>

</div>

This answer uses a min-width on the third and fourth td elements.

.container {
  width: 600px;
  overflow: scroll;
  border: solid 1px red;
}

table {
  table-layout: fixed;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
}


tbody tr td:nth-of-type(1),
tbody tr td:nth-of-type(2) {
  min-width: 100px;
}

tbody tr td:nth-of-type(3),
tbody tr td:nth-of-type(4) {
  min-width: 300px;
}

tbody td {
  color: #01216c;
  line-height: 18px;
  padding: 0 12px;
  height: 62px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
}

td>span {
  max-height: 62px;
  display: block;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
    </tbody>
  </table>

</div>

Increase the table container width.

Your table container has a fixed width of 600px which forces the divs to stretch as best they can. Increasing this or giving each a specific width would help to fit your content more.

Another practical, elegant and easy to implement solution is using overflow-y: auto; on table cells. Here are a couple of reasons why you should consider this instead of your current desired behavior:

  1. Resizing tables or table elements horizontally is suboptimal UX. Table based designs should only be used to display tabluar data by definition, and should generally have a fixed horizontal size and variable vertical size.
  2. Does not require any JS black magic in order to solve an otherwise basic problem of sometimes showing the user more text.
  3. We can also adjust the line-height to 20px for tds, this way we can comfortably see 3 text rows without showing a scroll bar. Bonus: some browsers such as Safari have actually nice looking scroll bars.

.container {
  width: 600px;
}

table {
  table-layout: fixed;
  min-width: 100%;
  overflow-x: auto;
}

tr > th:first-of-type, tr > td:first-of-type {
  min-width: 70px;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
  min-width: 124px;
}

tbody td {
  color: #01216c;
  line-height: 20px;
  padding: 0 12px;
  height: 62px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
  overflow-x: hidden;
  overflow-y: auto;
  min-width: 124px;
}

td > span {
  max-height: 62px;
  display: block;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa? Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus? Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa? Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum.</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
    </tbody>
  </table>
</div>

I have made 2 changes -

  1. add property overflow-y:auto to add vertical Scrollbar on fixed height cell for td>span
  2. change line-height: 1rem in tbody td properties or you change as per your requirement. Vertical space will be removed and less Y-Axis scroll required

.container {
  width: 600px;
  overflow: scroll:
}

table {
  table-layout: fixed;
  min-width: 100%;
  overflow-x: auto;
}

tr>th:first-of-type,
tr>td:first-of-type {
  min-width: 70px;
}

table thead th {
  border-top-color: #d9deea;
  border-bottom-color: #6b7790;
  border-style: solid none solid none;
  font-weight: 700;
  padding: 24px 12px;
  font-size: 14px;
  color: #6b7790;
  line-height: 16px;
  border-width: 1px;
  min-width: 124px;
}

tbody td {
  color: #01216c;
  line-height: 1rem;
  padding: 0 12px;
  height: 62px;
  font-size: 14px;
  border-width: 1px;
  border-bottom-color: #d9deea;
  border-style: none none solid none;
  overflow: hidden;
  min-width: 124px;
}

td>span {
  max-height: 62px;
  display: block;
  overflow-y:auto;
}
<div class="container">

  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
        <th>Header 4</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
      <tr>
        <td><span>Lorem ipsum.</span></td>
        <td><span>Lorem ipsum dolor sit.</span></td>
        <td><span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptas, minus?</span></td>
        <td><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo beatae quidem, molestiae sequi iusto amet voluptas maiores. Accusamus, dicta culpa?</span></td>
      </tr>
    </tbody>
  </table>

</div>

Related