April 2, 2014
Let’s talk about HTML tables.
Here’s some code:
<table class="main">
<colgroup><col class="votes"><col></colgroup>
<tr>
<td>Votes</td>
<td>Comments</td>
</tr>
<tr>
<td>
<p class="vote-desc">Some long name, really long, like really super long</p>
<p class="vote-desc">Another long name, really long</p>
</td>
<td>
<p class="comment">A really, really, really, really, really really really really really, really long comment.</p>
</td>
</tr>
</table>
In this table, there are two main data cells: one with two vote descriptions and one with a comment. Assuming the outside of the table has a constrained width, what will be the widths of the two inner data cells? Check out this jsfiddle. Now, check it out with a longer comment.
When I came across this situation in a project I was working on, I expected the left column to set its own width based on the width of its content, and for the subsequent columns to do the same with the remaining space. But no! In chrome and firefox, the left cell is all squished up, but the crazier thing is that chrome and firefox squish it up differently.
It turns out that this part of the HTML specification is actually non-normative. It’s called the automatic table layout algorithm. Basically, this applies to tables (elements with display: table
or display: inline-table
) with table-layout: auto
. [See end note.] From the spec:
"UAs are not required to implement this algorithm to determine the table layout in the case that ‘table-layout’ is ‘auto’; they can use any other algorithm even if it results in different behavior."
So, this is what really happens: the browser doesn’t know what to do when there are two columns that have to have automatically distributed width, so it makes its own decision.
In order to control the actual width of columns in a table, we have a couple of options. Since, according to the spec, setting table-layout: auto
can have unpredictable results, we should use table-layout: fixed
if we’re not sure of the length of the content that will occupy the table cells.
In this case, the browser will try to determine the width of the columns first by the widths of the column elements, second by the width of the cells in the first row of the column, and third by distributing total table width, if it is set, equally among columns (note that if it is not set, then the automatic table algorithm from above will be used, in some cases [see end note]). This is called the fixed table layout algorithm.
Here’s an example: much better!
The specification is a little shaky on what kind of algorithms should be used when for table width. Steps go like this, for a table
or inline-table
element:
table-layout: auto
, use the non-normative auto algorithm.table-layout: fixed
and has a width set, then use the normative fixed algorithm (aka, distribute equally) based on that width.table
or an inline-table
.
That is, the widths could still be non-normative if you use a fixed layout table with an automatic width. Maybe.
Tables are hard.
I'm Noah, a software developer based in the San Francisco Bay Area. I focus mainly on full stack web and iOS development