There is a CSS property for tables that, it seems to me, is well-supported, little known, and super useful. It changes the way that tables are rendered such that it gives you a sturdier, more predictable layout.
It is this:
table {
table-layout: fixed;
}
The default property for table-layout
is auto
, and that is the table layout I think most of us are familiar with. That style, to me, feels spongy and weird. Here’s an exploration:
See the Pen Default Tables are Weird. by Chris Coyier (@chriscoyier) on CodePen.
table-layout: fixed;
With Things get a lot sturdier and more predictable with property/value in place.
The layout is fixed based on the first row. Set the width of those, and the rest of the table follows.
It’s a little more complicated, but not much. Here’s an exploration:
See the Pen Fixed Tables Solve Some Issues by Chris Coyier (@chriscoyier) on CodePen.
Use Case
I explored this because I was trying to keep a uniform row height for Pens in list view on CodePen (i.e. not wrap Pen titles) but also not blow out the width of the table. This worked great.
I imagine most of you know this: tables are for tabular data and emails. Not web layouts, because reasons.
Practical HTML and CSS
I imagine most uses will be like this:
<table class="users">
<thead>
<tr>
<th class="row-1 row-ID">ID</th>
<th class="row-2 row-name">Name</th>
<th class="row-3 row-job">Job</th>
<th class="row-4 row-email">Email<th>
</tr>
</thead>
<tbody>
<tr>
<td>0001</td>
<td>Johnny Five</td>
<td>Robotin'</td>
<td>[email protected]</td>
</tr>
<tr>
<td>0002</td>
<td>Super Superlonglastnamesmith</td>
<td>Doin' stuff</td>
<td>[email protected]</td>
</tr>
</tbody>
</table>
.users {
table-layout: fixed;
width: 100%;
white-space: nowrap;
}
.users td {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Column widths are based on these cells */
.row-ID {
width: 10%;
}
.row-name {
width: 40%;
}
.row-job {
width: 30%;
}
.row-email {
width: 20%;
}
See the Pen xFcrp by Chris Coyier (@chriscoyier) on CodePen.
For good measure, know that you can use the <col>
element to set column widths too, because those effect the first row of cells and it’s all about that first row of cells setting the basis for the rest of the table.
Layout Speed
I’ve heard that this style of table layout is faster as well, which stands to reason because the contents of the entire table don’t need to be analyzed to know how big column widths are going to be. I don’t have any data on that though.
In Emails
Campaign Montior’s support chart for CSS in email clients shows table-layout as being supported across the board.
More Info
- Way more information about
<table>
s - table-layout on MDN. Include browser support, which basically amounts to ubiquitous.
Follow Up Tweets
@chriscoyier that's what I used to make ungrid, my responsive grid that's only 97 bytes http://t.co/RgIFjpcCXu
— Chris Nager (@chrisnager) July 2, 2014
@chriscoyier Chekkit: http://t.co/lO62D4lECK
— Harry Roberts (@csswizardry) July 2, 2014
@chriscoyier @twbootstrap is using this to handle horizontal button groups: https://t.co/dhLRuN0Jof
— Lucas Constantino (@luconsilva) July 2, 2014
@chriscoyier Chris, is there any reason to not just use table-layout: fixed all of the time?
— Mike Aparicio (@peruvianidol) July 2, 2014
When doing vertical alignment with
display: table;
anddisplay: table-cell; vertical-align: middle;
on its children, and one of the children contains an “ that you also want to scale and keep its ratio, I’ve had to usetable-layout: fixed
on the element withdisplay: table;
in order for it to play nice in Firefox.Apologies, the typo in my previous comment was supposed to be an
img
tag.Yes, I run into this constantly, vertically centering images with different dimensions in fixed ratio container, like in a product listing grid! The images scale nicely in Chrome, but in FF the images will bust out the container w/o table-layout: fixed.
Awesome as always, Chris. Thanks!
Great post but how come there’s no mention of colgroups and cols?
There is. I just didn’t dwell on it because I don’t find them particularly useful.
For my responsive emails, I only apply this to the outermost table. Otherwise kablooey.
Hi Chris,
Thanks for the tip! I had to use this recently as well and it is tremendously useful as you demonstrated clearly here.
I have a question about the last codepen example (the resizable one with text-overflow: ellipsis.) As you scale the width down, the first column of IDs gets the ellipsis properly. But when I shrink it down to it’s minimum width, the first column of IDs no longer have the ellipsis and instead just show 000 with the rest cut off as if with overflow: hidden.
Do you have any idea why this is? I’m just curious!
I noticed that too! Kinda weird. Maybe it’s like if it can’t fit the ellipsis it defaults back to the text. Which is weird and probably a bug. Or maybe not. Hard to say.
Btw, overflow is not supported on table cells in Firefox. The bug was filed way back in 2003 (https://bugzilla.mozilla.org/show_bug.cgi?id=221154) but crickets.
Yeah Firebox have different behavior of other browsers I got some bug because others browser handle the cell like a block but Firebox doesn’t do that and then I need to put a div inside the cell for fix it.
I have used this property for 2 projects already, but using it on DIV’s. The beauty is that a child element can have a fixed width, and the rest will just adapt.
You can see it in action on this page. The timeline at the bottom is made this way.
http://windpowerpioneers.vestas.com/timeline
The selected year will wrap to two lines atleast on Firefox when in specific browser widths. This is caused by
word-wrap: break-word;
which is a star rule. Is there a reason why you’ve applied this? Just seems to me like something that will cause tons of unexpected layout issues.Hi Vesa
You have got a good point. In this example I would remove the word-wrap. But generally I like to have it on the *, because clients tend to write some long words once in a while, or copy a long url to the content.
Nice one Chris.
Also, something completely different. There seems to be something wrong with your CDN…
Regarding: “And I’m 1000px wide. You’d think maybe it would be 1/3 as wide ultimately, but it doesn’t work like that.”
Isn’t that exactly what it is doing? That column is 1/3 the width of the other one, or 1/4 the width of the whole table (1000px out of 4000px total).
For me, it isn’t. It’s smaller than 1/4, exactly as wide as the longest word, which is “ultimately,”.
Yeah it actually does work like that.
I updated the example to be more clear, with one cell being 2000px wide and the other 1000px wide, it ends up 2/3 and 1/3.
Some more uses/examples http://csswizardry.com/2013/11/taming-data-tables/
I love
table-layout: fixed
. I’m still using it as a flexbox alternative until IE8 is safe to forget about. It makes it trivially easy to have a fluid-width item take up the remaining width of the container.IE9 doesn’t support Flexbox either though, are you just planning on jumping IE9 (with the user base being less than IE8) when you leave IE8?
My company ditched IE8 a long time ago and are getting ready to dump IE9 as well, but the use of
table-layout: fixed
was something that came in handy at times.I must be missing something – here’s what my attempt to czech out your code looks like: http://jsfiddle.net/clayshannon/8m8xr/
Add
text-align:left
property totable
elementUsing <col> in a table with fixed-layout really comes into its own when cells in the first row use ‘colspan=’.
Thanks!!!
i think table-layout:fixed is equal width
IE9 doesn’t assistance Flexbox either though, are you just preparing on moving IE9 (with the users list being less than IE8) when you keep IE8?
Thank you. I got burnt so often using table layouts in CSS “instead” of the conventional HTML table layouts that I eventually gave up and stuck with the HTML stuff completely. It is articles like yours that don’t use general verbiage without telling something concrete and useful, that I need to make it through “CSS rehab”. My problem is that I have a lot of legace XLS and ODT tables/databases with a lot of material that I wanted to get online and each time I tried it came apart “at the seams”.
Yeah it actually does work like that, Thank you