Search code examples
csshtml-tableresizeellipsis

CSS - HTML Table with dynamic width and ellipsis in header


I've got a table like the one below:

<table>
    <thead>
        <tr>
            <th>Col 1</th>
            <th>Column 2 header</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Column 1 content</td>
            <td>Column 2</td>
        </tr>
    </tbody>
</table>

What I'd like to achieve is the column's headers to have an ellipsis whenever its content is greater than the max content width of the column. So, for this table, the result should be something like:

Col 1 Column 2 h...
Column 1 content Column 2

As you can see, the first column has all the content visible because it's smaller than the column's TD's width, but the second column has its header with ellipsis.

Table layout like table-layout:fixed won't help, because that will make all columns with fixed (and equal) widths, and I don't want to set a width to any of the columns at all. They have different content, and that content comes from the server, so I don't know how long they will be.

The browser takes care of the resizing, and makes a pretty good job, but I need the headers not to be greater than the column's max content width, and if they are, apply ellipsis.

I've tried to create a <div> within the <th> to set it with width: 100% and all the ellipsis-like styles (white-space: nowrap; overflow: hidden;...), but that just makes the table to expand its width and none of the TH's have ellipsis, all the content is always visible in one line.

I've also searched for the net and stackoverflow, but all the questions seem to be old or they don't really take into account the "dynamic" part of it.

Is there any way to get the header width not to be greater than the column's width, and if it was, apply ellpsis to it, using just CSS properties?

Thank you.


Solution

  • If you are able to add an extra wrapper you can do like below. Using contain: inline-size you tell the browser to ignore its content when defining the inline-size (the width in your case).

    table,
    tr > * {
      border: 1px solid;
    }
    
    span {
      display: block;
      contain: inline-size; /* the content won't affect the size */
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
    <table>
      <thead>
        <tr>
          <th><span>Col 1</span></th>
          <th><span>Column 2 header</span></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Column 1 content</td>
          <td>Column 2</td>
        </tr>
      </tbody>
    </table>