Arieh.co.il

Whats display:table?

Yesterday night I was doing a pass in this forum when I came across a question about display:table. Considering the fact that in the last 3 years at least I haven't run into even one guide discussing this attribute, I always assumed it's broken are unusable, but just to answer my curiosity, I decided to go on and write some tests. Following are the results of these tests.

Basic rules

First of all, we need to understand what the display:table* are for. We all know that designing with tables is wrong, semantically wise. But the reason the problem occurred in the first place was that for some unknown reason, all browsers developed a pretty useful flow mechanism for tables.

A row will always expand as much as the longest row in the table will expand (unless the table itself has a limit that is). All cells in a row will automatically space themselves properly within their row, and will also adjust their height to that of the highest cell in their row. This is, as far as I know, the only rule in css that allows normal, usable vertical alignment in CSS/HTML.

Since the abandonment of table layouts, once of the most discussed topics out there is the 3-column-auto-height css columns fixes. Some of the more interesting can be found here and here.

So far, this is all but trivial. The interesting bit is that at least by principle, the display:table* attribute set exposes the above layout mechanism to designers, separated from it's markup.

Or so I thought. Reading the specs, I understood (I think) why developers never really got into this pattern (backward compatibility put aside - I haven't seen even one experiment with this). When using this layout, we must have:

  1. A container to function as the table tag - having a display:table.
  2. An element that needs to function as a tr tag - having a display:table-row.
  3. Finally, we also need a cell - a td replacement - with display:table-cell.

So basically, we need a table. Or at least a markup that requires as much garbage as a normal table will provide. A simple markup will look like:

    <div id="table">
    	<div class="row">
    		<div class="cell">aa bb cc dd ee</div>
    		<div class="cell" id='test1'>aa bb</div>
    		<div class="cell">cc dd ff</div>
    	</div>
    </div>

The styling will go like this:

#table{
    display:table;
    margin:0 auto;
    width:500px;
}

#table .row{
    display:table-row;
}

#table .cell{
    display:table-cell;
    border:1px solid #000;
}

#test1{ height:60px;}

The result:

aa bb cc dd ee
aa bb
cc dd ff

Now, you will say, why the hell will we want to have this much markup? We're doing just fine without it. And you will be right. At first glance, this is completely useless.

A second glance

Here's the thing. In some of my recent work, I've been using the body tag to replace some of the usage we usually get from a wrapper div. I mean - if all we have is a body>div, and the body itself isn't even styled, why not drop the div? The next step was to start looking at the html tag as stylable. A good example of this can be found here.

So if we already have some markup we aren't using, why shouldn't we do the same for our 3 columns layout? We can then do:

html{
    display:table;
}   

body{
    display:table-row;
}

body > * {
    display:table-cell;
}
And with this pseudo markup:
<html>
	<body>
		<div id="left"></div>
		<div id="main"></div>
		<div id="right"></div>
	</body>
</html>

We will have a magnificent, 3-column, auto-height solution. A slightly styled version can be found here. I suggest you take a look on the code to see how the magic is applied. This looks the same on all supporting browsers that I checked (IE8 included). This is not a trivial thing.

On a third glance

But even for the above, there's a problematic issue: on table layout, rows can't be given width, only tables. The result is that I had to give a width to the html tag. This is a bad idea. Here's PPK on the subject.

This means that in order for this to work, we should at least have one extra wrapper, and with that, we already have a markup we can style normally without display:table.

If that's not enough, we also have the fact that IE < 8 do not support this attribute. Also, since this is a rare use case, we have no idea of it's quirks.

Still, this is a cool feature, and I have the feeling that with some extra tests, we might have a use case for this one along the road (maybe when we stop supporting IE7?).

JavaScript Reference, JavaScript Guide, JavaScript API, JS API, JS Guide, JS Reference, Learn JS, JS Documentation