Why display: table shouldn’t be frowned upon
I’ve seen a lot of commentary on the for, and against of using the CSS property display: table, a lot of it negative. It takes us back to the dark ages, using tables for layout. These people tend to forget that CSS is purely presentational and setting something as display: table is not the same as using the table tag. A screen reader going over a layout styled using the CSS table model will not get confused and muddled up. It will in fact breeze through a layout done correctly no matter which technique used floats or CSS tables. The display properties values: table, table-cell, table-row etc are named due to the fact its presentational result is that best described of how a table would work and the similarities end there.
Let’s take a look at a few examples of layouts done with display: table and show you some advantages. You will in fact see a lot of reduced mark-up in favour of using the CSS tables’ method. It should be noted that the following techniques do not work in IE6 or IE7 (despite this being in the CSS 2.1 spec) but it is finally supported in IE8. Therefore it’s not recommended to use in real world environments, but that doesn’t mean we still can’t have fun.
The run down
In this example I will do a simple header, content, footer layout but with one twist this layout stretches both vertically and horizontally creating a true fluid layout without the use of hacks or CSS voodooism.
The xhtml
<div id="maincontainer"> <div id="header"> <p>Header</p> </div> <div id="content"> <div class="container"> <p>Content</p> </div> </div> <div id="footer"> <p>Footer</p> </div> </div>
The CSS
/* Makes the layout expand to 100% height. Without this CSS below won't work */ html,body { height: 100%; } #maincontainer { display: table; height: 100%; width: 100%; } /* Basic table layout */ #maincontainer #header, #maincontainer #content, #maincontainer #footer { display: table-row; } #maincontainer #header { height: 150px; background-color: green; } #maincontainer #content { height: 100%; background-color: #000000; color: #ffffff; } #maincontainer #content .container { display: table-cell; padding: 10px; } #maincontainer #footer { height: 80px; background-color: purple; }
The run down
Now we’ll take a look at a technique that isn’t easily accomplished in the good browsers, I’m of cause speaking of vertical centring. With the use of table display property we can accomplish this with very little mark-up and CSS.
The xhtml
<div id="maincontainer"> <div class="table-cel"> <div class="box01"> <p>Horizontally and vertically centred!</p> </div> </div> </div>
The CSS
/* Makes the layout expand to 100% height without this CSS below won't work */ html,body { height: 100%; } #maincontainer { display: table; height: 100%; width: 100%; } /* Vertical centre */ .table-cel { display: table-cell; vertical-align: middle; text-align: center; background-color: #000000; } .table-cel .box01 { margin: 0 auto; text-align: left; width: 500px; height: 500px; background-color: orange; } .table-cel .box01 p { text-align: center; line-height: 500px; }
These 2 examples only scratch the surface of the power that the table display property gives you. With Microsoft finally adding support in IE8 these techniques will only become more viable.
I was a little skeptical of the first fluid layout and its ability to support more content than the browser height. I added more content and (as expected) it runs off the paged without the vertical scroll-bar.
Have you found a way to enable the scroll-bar when needed by the content?
I’m using Firefox 3.0.10
Jonathan, June 12th, 2009Thanks for comment Jonathan. You are correct that this will cut off any content that flows past the current window height. Luckily this can be fixed and I have updated the demo files and the source download, I will also update the article when I have more time. You can view the overflow example here. This hasn’t been thoroughly tested but it works in Safari 4, FF3/2/1.5 and IE8.
The changes made was removing the overflow: hidden from the html, body selector as this was causing the overflow to be hidden and was unnecessary. I added another container inside the #content container and gave it display: table-cell so padding could be applied, table-row will ignore padding.
The Css Ninja, June 12th, 2009Sweet. Thanks for sharing :)
Jonathan, June 17th, 2009thz, you made my evening better :)
Vali, December 8th, 2010ups…
Of course using tables instead of CSS to display tabular data, is not a sin either.
Iouri Goussev, December 23rd, 2010In fact NOT using tables to display tabular data is bad. The whole point is whether a screen reader can figure out what it’s looking at based on your markup. A bunch of divs or lists used improperly is poor practice.
Erik, June 10th, 2011Thanks, usefull
Catalin, October 25th, 2011I have noticed a weirdness that if I want to vertically align content in a table-cell, I need to specify an absolute height: no 100% or min-height.
http://jsfiddle.net/smlombardi/LnD3b/11/
Anyone else? Workarounds? I don’t want to have to specify a height.
Steve, December 13th, 2011