How to truncate text in a table column?

Viewed 1522

I am trying to create a table where each column fits the width of the content (just like a normal table), but when the content would push the table beyond 100% of the container width, certain long columns would be truncated with an ellipsis.

+-------------+------------+------+
|some content | short text | more |
+-------------+------------+------+

+-------------+------------------------------------------------+------+
|some content | much longer text that forces the table wide... | more |
+-------------+------------------------------------------------+------+

It appears that any use of text-overflow: ellipsis requires a fixed-width table, and perhaps fixed-width columns. This is unfortunate because columns will no longer adjust their widths to fit content automatically.

I'm not tied to using a <table>. I've also attempted to do it using Bootstrap's col-auto. col-auto adjusts the width of the column to the content, but like <table> it refuses to truncate text when the table gets too wide.

Is this even possible?

Here's a fiddle: https://jsfiddle.net/nsf04tce/2/

1 Answers

There is a way to achieve this without setting the width of the 'long' table cell.

Here are the ingredients:

Add border-collapse: collapse and table-layout: fixed to the table class and give a width instead of a max-width.

  • The border-collapse: collapse will give all cells one shared border.
  • The table-layout: fixed sets a fixed width.
  • Use width to set a fixed width instead of a max-width (can grow to...).

Next to this, add overflow: hidden to the long table cell (next to the initial additions you made), so it knows what to do if the content overflows.

In CSS:

.mytable {
    border-collapse: collapse;
    width: 400px;
    table-layout: fixed;
}

.long-td {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

Demo:

td {
  border: 1px solid;
}

.mytable {
  border-collapse: collapse;
  width: 400px;
  table-layout: fixed;
}

.long-td {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
max-width on the table is ignored when nowrap and text-overflow is present:
<table class="mytable">
  <tr>
    <td>short</td>
    <td class="long-td">long long long long long long long long long long long long long long long long long long long long long long long long </td>
    <td>short</td>
  </tr>
</table>

EDIT

If you are not bound to use of a table, you could use a div with span elements inside. The .mytable div gets display: flex and flex-flow: row nowrap to make sure it stretches out.

CSS:

.mytable {
    display: flex;
    flex-flow: row nowrap;
    width: 100%;
}

span {
  border: 1px solid;
}

.mytable {
  display: flex;
  flex-flow: row nowrap;
  width: 100%;
}

.long-td {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
max-width on the table is ignored when nowrap and text-overflow is present:
<div class="mytable">
  <span>short</span>
  <span class="long-td">long long long long long long long long long long long long long long long long long long long long long long long long </span>
  <span>short</span>
</div>

EDIT 2

If you could use display: grid, you could specify a grid where the middle column is auto or a multiplier of a (fr)agment, like 4fr. You could set the first and last column to a specified width. There are a lot of options for grid-template-columns, see the documentation on MDN.

.mytable {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
}

div > div {
  border: 1px solid;
}

.mytable {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
}

.long-td {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
max-width on the table is ignored when nowrap and text-overflow is present:
<div class="mytable">
  <div>short</div>
  <div class="long-td">long long long long long long long long long long long long long long long long long long long long long long long long</div>
  <div>shorter story</div>
    <div>short</div>
  <div class="long-td">Suspendisse cursus ornare rutrum. Pellentesque sollicitudin bibendum odio, vitae euismod ligula.</div>
  <div>shorter story</div>
</div>

Related