Gikkman
Gikkman

Reputation: 762

text-overflow: ellipsis; in table cell

I have a page with a table, which is updated periodically. The table has a heading, followed by a number of rows. Each row has 3 fields: Player position, Player name (also a link to the player's profile), and the player's time. The table takes up the entire page width.

The html looks like this:

<table id="raceTable">
  <tbody>
    <tr><th colspan="3">3 Players</th></tr>
    <tr><td>1st</td><td><a>Link to profile of player A</a></td><td>00:22:12</td></tr>
    <tr><td>2st</td><td><a>Link to profile of player B</a></td><td>00:23:12</td></tr>
    <tr><td>3st</td><td><a>Link to profile of player C</a></td><td>00:24:15</td></tr>
  </tbody>
</table>

Now, I want to make the table scalable. If the user changes the width of the window, the table should be resized, the text in the middle column should be clipped when it doesn't fit.

This is the CSS I've tried:

body{
  overflow: hidden;
}

table {
    width:100%;
    line-height: 50px;
    border-collapse: collapse;
}

th {
    height: 50px;
    width: 100%;
    background-color: magenta;
}

td {
   height: 50px;
}

#raceTable {
    width: 100%;
}

#raceTable > tbody > tr:not(:first-child) > td:nth-child(1) {
  padding: 10px;
  background-color: red;
  float: left;
}

#raceTable > tbody > tr:not(:first-child) > td:nth-child(2) {
  width: 100%;
  background-color: gray;
}

#raceTable > tbody > tr:not(:first-child) > td:nth-child(2) > a{
  display: block;
  background-color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}  

#raceTable > tbody > tr:not(:first-child) > td:nth-child(3) {
  padding: 10px;
  background: green;
  float: right;
}

And I have a JSFiddle of it all here: http://jsfiddle.net/Gikkman/5wpts61p/17/

My question is, how do I make text-overflow: ellipsis; to work for the link text in the middle column of the table? I cannot change how the HTML of the site is structured, I can only apply CSS. Is this possible?

Upvotes: 1

Views: 6350

Answers (2)

G-Cyrillus
G-Cyrillus

Reputation: 105903

after reconsidering my comment, I would still advise to style your table with table-layout:fixed; and reset default display on a as you did, but build it with a little more table elements.

https://www.w3.org/wiki/HTML/Elements/colgroup

https://www.w3.org/WAI/UA/TS/html401/cp1001/1001-COL-COLGROUP.html

table {
  width:100%;
  table-layout:fixed;
  line-height:50px;
}
thead {background:green;}
td {width:100%;}
col {background:gray;}
col:first-child, col:last-child {
  width:4em;
  background:red;
}
col:last-child {
  background:cyan;
}
a {  display:block;
  background-color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  width:100%;}
<table id="raceTable">
  <colgroup>
    <col/>
    <col/>
    <col/>
    </col>
  <thead>
    <tr>
      <th colspan="3">3 Players</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1st</td>
      <td><a>Link to profile of player A</a></td>
      <td>00:22:12</td>
    </tr>
    <tr>
      <td>2st</td>
      <td><a>Link to profile of player B</a></td>
      <td>00:23:12</td>
    </tr>
    <tr>
      <td>3st</td>
      <td><a>Link to profile of player C Link to profile of player C Link to profile of player C</a></td>
      <td>00:24:15</td>
    </tr>
  </tbody>
</table>

https://jsfiddle.net/bn2trf2o

What happens here is the colspan attribute on th and table-layout:fixed; that shares evenly the columns.

To avoid this confusion, you can use the colgroup and col tags to init each width for each columns. Size first and last , the middle will use all space left.You can use them also to set a background defaut color for each columns. it will be hidden as soon as you set a bg on any other elements(like thead does in the snippet)


edit

from your structure , a display reset on trs could do :

table,
tr {
  width: 100%;
  table-layout: fixed;
  line-height: 50px;
  border-spacing: 0;
}

tr {
  display: table;
}

th {
  background: magenta
}

td {
  background: gray;
}

td:first-child,
td:last-child {
  width: 30px;
  background: red;
}

td:last-child {
  background: cyan;
  width: 100px;
}

a {
  display: block;
  background-color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
<table id="raceTable">
  <tbody>
    <tr>
      <th colspan="3">3 Players</th>
    </tr>
    <tr>
      <td>1st</td>
      <td><a>Link to profile of player A</a></td>
      <td>00:22:12</td>
    </tr>
    <tr>
      <td>2st</td>
      <td><a>Link to profile of player B</a></td>
      <td>00:23:12</td>
    </tr>
    <tr>
      <td>3st</td>
      <td><a>Link to profile of player C Link to profile of player C Link to profile of player C</a></td>
      <td>00:24:15</td>
    </tr>
  </tbody>
</table>

https://jsfiddle.net/bn2trf2o/1/

Upvotes: 3

Stickers
Stickers

Reputation: 78686

In table, text-overflow: ellipsis; only works with fixed table layout, normally you can just apply:

#raceTable {
  table-layout: fixed;
  width: 100%;
}

But it looks like you also want to have dynamic width for the columns. In that case you can wrap the <a> with a <div> to create a CSS fixed table layout structure, then apply the text overflow on it.

#raceTable td:nth-child(2) div {
  display: table;
  table-layout: fixed;
  width: 100%;
}
#raceTable td:nth-child(2) a {
  display: table-cell;
  background-color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

#raceTable {
  line-height: 50px;
  border-collapse: collapse;
  width: 100%;
}

#raceTable th {
  height: 50px;
  background-color: magenta;
}

#raceTable td {
  height: 50px;
}

#raceTable td:nth-child(1) {
  padding: 10px;
  background-color: red;
  /* float: left; */
}

#raceTable td:nth-child(2) {
  width: 100%;
  background-color: gray;
}

#raceTable td:nth-child(2) div {
  display: table;
  table-layout: fixed;
  width: 100%;
}

#raceTable td:nth-child(2) a {
  display: table-cell;
  background-color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

#raceTable td:nth-child(3) {
  padding: 10px;
  background: green;
  /* float: right; */
}
<table id="raceTable">
  <thead>
    <tr>
      <th colspan="3">3 Players</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1st</td>
      <td><div><a>Link to profile of player A, Link to profile of player A, Link to profile of player A</a></div></td>
      <td>00:22:12</td>
    </tr>
    <tr>
      <td>2st</td>
      <td><div><a>Link to profile of player B</a></div></td>
      <td>00:23:12</td>
    </tr>
    <tr>
      <td>3st</td>
      <td><div><a>Link to profile of player C</a></div></td>
      <td>00:24:15</td>
    </tr>
  </tbody>
</table>

Upvotes: 4

Related Questions