romellem
romellem

Reputation: 6503

Have table cell grow horizontally when cell content is large

I have a table within a wrapper div that is set to scroll on overflow (i.e., overflow: auto;).

This works nicely when placed in a container div that has a fixed width. If my table (which is being built server side) happens to have a lot of columns and gets too wide, gets a scroll bar placed at the bottom, making it semi-mobile friendly.

<div class="container">
  <div class="wrapper">
    <table>
      <!-- more html here... -->
    </table>
  </div>
</div>
.container {
  width: 350px;
}

.wrapper {
  width: 100%;
  overflow: auto;
}

table {
  width: 100%;
}

However, when I have a cell which contains a lot of text, the cell will typically grow in height to fit the content.

Since I'm using a scrolling overflow, I'd like for the cell to tend to grow more in width, which would give it a better visual appeal.

Here are some examples:

.container {
  width: 350px;
}

.wrapper {
  width: 100%;
  overflow: auto;
}

table {
  width: 100%;
}

/* Manual fix for cell with lots of text */
.manual-fix {
  width: 400px;
}

/* minor display stuff */

hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible;
}

h1 {
  font-size: 1.2em;
}

h2 {
  font-size: 0.9em;
  font-weight: normal;
  font-style: italic;
}

table tr td {
  border: 1px solid grey;
  padding: 0.5em;
}

table tr th {
  background-color: grey;
  color: white;
  padding: 0.3em;
}

body {
  font-family: sans-serif;
}
<h1>
Table within a wrapper so it overflows nicely and you can scroll.
</h1>
<div class="container">
  <div class="wrapper">

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>lorem</td>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
        </tr>
        <tr>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td>lorem</td>
        </tr>
        <tr>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td>lorem</td>
          <td>ipsum</td>
        </tr>
      </tbody>
    </table>

  </div>
</div>

<h1>
Table still within a wrapper yet coincidentally fits without the need for a scrolling overflow.
</h1>

<h2>
This is only because it has a small number of columns.
</h2>
<div class="container">
  <div class="wrapper">

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>lorem</td>
          <td>ipsum</td>
          <td>dolorcing</td>
        </tr>
        <tr>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
        </tr>
        <tr>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
        </tr>
      </tbody>
    </table>

  </div>
</div>

<hr>

<h1>
Table that still overflows, but wraps long text poorly.
</h1>
<div class="container">
  <div class="wrapper">

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>lorem</td>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
        </tr>
        <tr>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
        </tr>
        <tr>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td>lorem</td>
          <td>ipsum</td>
        </tr>
      </tbody>
    </table>

  </div>
</div>

<h1>
Table with a "manual fix" in place what I'd like to automatically happen when a cell has a lot of text in it.
</h1>
<h2>
Essentially, I'd like for a cell to have a max height, and increase its width when it reaches that max height so the content doesn't overflow.
</h2>
<div class="container">
  <div class="wrapper">

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>lorem</td>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
        </tr>
        <tr>
          <td>ipsum</td>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td><div class="manual-fix">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
        </tr>
        <tr>
          <td>dolorcing</td>
          <td>sit</td>
          <td>amet</td>
          <td>lorem</td>
          <td>ipsum</td>
        </tr>
      </tbody>
    </table>

  </div>
</div>

At the bottom example, I've manually expanded the width of a cell with large amounts of text to show what I'd like to happen (without the manual fix, of course).

Essentially, what I'm looking for is when a cell has a lot of text, for that cell to have a maximum height, and for the cell to expand horizontally (rather than vertically) to fit the content.

Upvotes: 0

Views: 5415

Answers (3)

Oriol
Oriol

Reputation: 288700

You can wrap the cell contents inside a non-tabular container with

width: max-content;     /* Attempt to have maximum width required by content */
max-width: 400px;       /* without exceeding 400px */
min-width: min-content; /* unless the content really requires it (optional) */

In the future, it will be possible to write this as

width: fit-content(400px);

Note not all browsers support max-content or min-content, and others need vendor prefixes.

.container {
  width: 350px;
}

.wrapper {
  width: 100%;
  overflow: auto;
}

table {
  width: 100%;
}

/* Manual fix for cell with lots of text */
.manual-fix {
  width: 400px;
}

/* minor display stuff */

hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible;
}

h1 {
  font-size: 1.2em;
}

h2 {
  font-size: 0.9em;
  font-weight: normal;
  font-style: italic;
}

table tr td {
  border: 1px solid grey;
  padding: 0.5em;
}

table tr th {
  background-color: grey;
  color: white;
  padding: 0.3em;
}

body {
  font-family: sans-serif;
}

td > div {
  width: -webkit-max-content;
  width: -moz-max-content;
  width: max-content;
  max-width: 400px;
  min-width: -webkit-min-content;
  min-width: -moz-min-content;
  min-width: min-content;
}
<h1>
  Table within a wrapper so it overflows nicely and you can scroll.
</h1>
<div class="container">
  <div class="wrapper">
    <table>
      <thead>
        <tr>
          <th><div>1</div></th>
          <th><div>2</div></th>
          <th><div>3</div></th>
          <th><div><div>4</div></th>
          <th>5</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><div>lorem</div></td>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
        </tr>
        <tr>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
          <td><div>lorem</div></td>
        </tr>
        <tr>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
          <td><div>lorem</div></td>
          <td><div>ipsum</div></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<h1>
  Table still within a wrapper yet coincidentally fits without the need for a scrolling overflow.
</h1>

<h2>
  This is only because it has a small number of columns.
</h2>
<div class="container">
  <div class="wrapper">
    <table>
      <thead>
        <tr>
          <th><div>1</div></th>
          <th><div>2</div></th>
          <th><div>3</div></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><div>lorem</div></td>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
        </tr>
        <tr>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
        </tr>
        <tr>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<hr>

<h1>
  Table that still overflows, and wraps long text nicely.
</h1>
<div class="container">
  <div class="wrapper">
    <table>
      <thead>
        <tr>
          <th><div>1</div></th>
          <th><div>2</div></th>
          <th><div>3</div></th>
          <th><div>4</div></th>
          <th><div>5</div></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><div>lorem</div></td>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
        </tr>
        <tr>
          <td><div>ipsum</div></td>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
          <td><div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
        </tr>
        <tr>
          <td><div>dolorcing</div></td>
          <td><div>sit</div></td>
          <td><div>amet</div></td>
          <td><div>lorem</div></td>
          <td><div>ipsum</div></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Upvotes: 3

Pushpendra
Pushpendra

Reputation: 1712

Add position:relative; to .container class

Please find the working example here. Pen

Upvotes: 0

Jeaf Gilbert
Jeaf Gilbert

Reputation: 12021

Cell column won't grow wider on fixed width table. Give wrapper a lot of space for table to grow. Then with javascript (I use jQuery), adjust wrapper width to fit table's width.

CSS

.container {
   width: 350px;
   overflow:auto;
}

.wrapper {
  width: 10000px;
}

table { 
}
table td:nth-child(5) {
  max-width:400px;
}

jQuery

$(document).ready(function() {
  $('table').each(function() {
    $(this).closest('.wrapper').width($(this).outerWidth());
  })
})

Here's the fiddle.

Upvotes: 0

Related Questions