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
orwhite-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
CSS Floats, Change Order on Mobile Layout
How to Tell Which Font Chrome Is Using
Selector for One Tag Directly Followed by Another Tag
Center Align Position Absolute Object Horizontally
Positioning a "Wrapper" Div Underneath a Fixed Navigation Bar
How to Pass !Important as Parameter/Option for Lesscss Mixins
Converting Between Physical Pixels and CSS Pixels
Responsive Images Positioned Over Image
Is CSS Faster When You Are Specific
Font-Feature-Settings: What Is the Correct Syntax
CSS Transition from 'Display: None' on Class Change
How to Hide Default Choose File Button
How to Filter and Show Only Applied CSS in Chrome Developer Tools (Like Firebug in Firefox)