CSS Percentage Width and Text-Overflow in a Table Cell

CSS percentage width and text-overflow in a table cell

This is easily done by using table-layout: fixed, but "a little tricky" because not many people know about this CSS property.

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

See it in action at the updated fiddle here: http://jsfiddle.net/Fm5bM/4/

CSS text-overflow table cell with percentage max width

This cannot work with a standard HTML table: the automatic layout algorithm will keep stretching cells so they can always fit their contents, even ignoring explicit widths.

Switch to table-layout:fixed and everything will work as intended.

CSS text-overflow in a table cell?

To clip text with an ellipsis when it overflows a table cell, you will need to set the max-width CSS property on each td class for the overflow to work. No extra layout div elements are required:

td
{
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

For responsive layouts; use the max-width CSS property to specify the effective minimum width of the column, or just use max-width: 0; for unlimited flexibility. Also, the containing table will need a specific width, typically width: 100%;, and the columns will typically have their width set as percentage of the total width

table {width: 100%;}
td
{
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
td.column_a {width: 30%;}
td.column_b {width: 70%;}

Historical: For IE 9 (or less) you need to have this in your HTML, to fix an IE-specific rendering issue

<!--[if IE]>
<style>
table {table-layout: fixed; width: 100px;}
</style>
<![endif]-->

Understanding CSS table-cell and percentage width

This has to do with how automatic table layout works. In particular:

A percentage value for a column width is relative to the table width. If the table has 'width: auto', a percentage represents a constraint on the column's width, which a UA should try to satisfy. (Obviously, this is not always possible: if the column's width is '110%', the constraint cannot be satisfied.)

In your case, you're setting a minuscule percentage width on every table-cell element. But the browser needs to ensure that the table-cells fill up the width of the table (which itself is as wide as its containing block), so it has to expand the cells to occupy as much space within the table as possible.

The reason why this results in approximately equal-width cells is because the percentage value is equal for all of them. If, for example, you set a slightly larger width for one of the cells, you'll see that it grows wider and the other cells become narrower to accommodate:

div {

border: 1px solid #000;

border-radius: 4px;

}

div ul {

padding: 0;

margin: 0;

}

div ul li {

display: table-cell;

width: 1%;

text-align: center;

border-right: 1px solid #000;

padding: 10px 0;

}

div ul li:first-child {

width: 3%;

}

div ul li:last-child {

border-right: 0;

}
<div>

<ul>

<li><a href="#">Commits</a>

</li>

<li><a href="#">Branch</a>

</li>

<li><a href="#">Contribution</a>

</li>

<li><a href="#">anything</a>

</li>

</ul>

</div>

Strange behavior on table and table-cell with percentage width

The auto tabular layout is not specified by the standard, so I recommend against using this kind of percentage tricks, which will probably break on some browsers.

However, it seems most browsers behave like this:

  • The ::before and ::after pseudo-elements will take the specified percentage of the table.
  • The text is wrapped inside an anonymous cell which has the width of the text. That will represent the remaining percentage left by the pseudo-elements.
  • The width of the table will be determined by the constraints above.

So if you have width: 25%, the text will take the remaining 50%.

tablewidth = textwidth / 50% = 2 * textwidth
pseudowidth = 25% * tablewidth = 0.5 * textwidth

If you have width: 40%, the text will take the remaining 20%.

tablewidth = textwidth / 20% = 5 * textwidth
pseudowidth = 40% * tablewidth = 2 * textwidth

If you have width: 45%, the text will take the remaining 10%. That is, the table will double its width with respect to the previous case, if the text is the same.

tablewidth = textwidth / 10% = 10 * textwidth
pseudowidth = 45% * tablewidth = 4.5 * textwidth

Of course, things start to get tricky if the desired table width calculated as described above exceeds the containing block. Then

  • The table will be as wide as the containing block
  • The text cell will have the width resulting of resolving the remaining percentage left by the pseudo-elements. That will be less than the preferred width of the text, so the text will wrap into multiple lines.

    However, the text cell won't be narrower than the minimum required width of the text. That will usually be the width of the longest word, but may change due to e.g. word-break: break-all or white-space: nowrap.

  • The remaining space left by the text will be equally distributed among the pseudo-elements.

    If the remaining space is negative, the pseudo-elements will have 0 width, and the table will grow (overflowing the containing block) in order to compensate that.

Make display table-cell use percentage width

You're almost there. You just need to add display: table and width: 100% to your ul.group2. You could probably also get away with not supplying a width on your .group2 p elements.

This should work: http://jsfiddle.net/6Kn88/2/

ul {

margin: 0;

padding: 0;

list-style: none;

}

.group {

width: 50%;

margin-bottom: 20px;

outline: 1px solid black;

background: white;

box-shadow: 1px 1px 5px 0px gray;

-webkit-box-sizing: border-box;

-moz-box-sizing: border-box;

box-sizing: border-box;

}

.group h2 {

display: block;

font-size: 14px;

background: gray;

text-align: center;

padding: 5px;

}

.group li {

clear: both;

}

.group p {

padding: 3%;

text-align: center;

font-size: 14px;

}

.group2 ul {

display: table;

width: 100%;

}

.group2 li {

display: table-row;

}

.group2 p {

display: table-cell;

vertical-align: middle;

width: 46%;

border-bottom: 2px solid gray;

}

.group li:last-child p {

border-bottom: 0;

}
<div class="group group2">

<h2>Health Indicies</h2>

<ul>

<li><p class="parameter">GGP</p><p class="data">265</p></li>

<li><p class="parameter">Comfort</p><p class="data">blah</p></li>

<li><p class="parameter">Energy</p><p class="data">gooo</p></li>

</ul>

<span class="clear"></span>

</div>

How table-cell width with percentage value works?

Here's the Math:

table-cell's width on 100% means that you have a table with a single cell per row. The known width - in your case - is the width of the text (89px).

If we put table-cell's width at 50%, that means the cell is wider as half of the whole table's width. We double the known width going to 178px.

Conclusion, the end width will be 100 / {table-cell's width} * {element's offsetWidth}

Why this happens is explained with the already posted link http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes

Table-cell with fixed percentage doesn't work with many items

If you change the table-layout property to fixed for the .container element, it resolves the issue:

Updated Example

.container {
border: 1px solid gray;
display: table;
table-layout: fixed;
width: 100%;
}


Related Topics



Leave a reply



Submit