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
Thanks 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.
Sweet. Thanks for sharing :)
thz, you made my evening better :)
ups…
Of course using tables instead of CSS to display tabular data, is not a sin either.
In 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.
Thanks, usefull
I 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,
From what I’ve read setting a fixed height (e.g. height: 600px;) on a table or table-cell actually works as min-height. The element will continue to grow if you paste longer content in (I tried that in the jsfiddle and got the desired result). I’ve only tested on Chrome, Safari and Firefox on Mac so I’m unsure of IE but that is the behavior as I’ve read for display table. Hope that helps.
I was asking myself if the layout can be used on a fixed width layout. I was trying but it gives problems with the footer when browser is minimized
I’m trying to create two tables side by side that both have the same height in IE8. The tables are both inside table-cells set to 50% each (I’m creating a liquid layout). The problem is that the table on the left has more height than table on the right (due to more content). I’ve tried height: 100% on both tables, but it doesn’t work. Any suggestions?