Layout Secret Weapon #1: The CSS Table Property

Originally published at: http://www.sitepoint.com/solving-layout-problems-css-table-property/

Man at a Table

Photo credit: Craig Sunter

Right now Flexbox is arguably THE hot new thing for layout building. Flexbox's almost miraculous abilities to adapt to the available space has left many of us wide-eyed with possibility.

Nevertheless it can not solve all your layout problems and moreover it brings with it some compatibility issues with legacy browsers. There simply is no bulletproof ‘polyfill’ (fallback for older browsers) for Flexbox — currently I'm only aware of a polyfill for the 2009 version of IE: Flexie.

In many cases I've found simpler solutions using the often-ignored CSS table displays properties. These CSS properties are widely supported by all relevant browsers (note this excludes IE6 & 7), and can elegantly solve several major and small layout headaches.

In case you're not 100% familiar with this technique, changing a DIVs display property can make it behave like a table or a table element.

Wait what? Tables for layout? Isn’t that bad?

Perhaps the hottest web design topics of the early 2000's was the debate over using HTML table code as a layout tool. That was a hack and is still bad practice.

Instead here we're using perfectly meaningful HTML (i.e. DIVs, SECTIONs, HEADERs, etc) and simply borrowing some useful table presentation know-how from CSS. This is precisely what CSS was designed to do, so don't feel that this is a hack or patch. It’s not.

Using 'display:table-cell'

In the sample below, clicking the top button you can change the display property of the three colored DIVs from block to table-cell:

See the Pen Display table #1 by Massimo Cassandro (@massimo-cassandro) on CodePen.

You can see how the DIVs can be horizontally arranged without requiring any float property, and that you can also access some typical table rules (just like vertical-align).

If you need some spacing, note that the classic CSS margin property doesn't have any effect on table cells: instead use border-spacing instead (it must be applied to the container table element). You can find some commented lines within the Codepen, if you want to play with those rules.

This technique can be very useful to solve a lot of problems that prove difficult to crack other ways.

I've picked out three simple cases where the table display properties are really valuable.

But first let's look at them:

| display property    | renders as |
|---------------------|:----------:|
| table, inline-table |    table   |
| table-column        |     col    |
| table-column-group  |  colgroup  |
| table-row-group     |    tbody   |
| table-header-group  |    thead   |
| table-footer-group  |    tfoot   |
| table-row           |     tr     |
| table-cell          |     td     |
| table-caption       |  caption   |

For a really comprehensive guide to tables and CSS take a look at CSS Tricks: A Complete Guide to the Table Element.

Case 1. Equal height boxes

I think this is one of the most frequent issues I've deal with: there are some floated boxes with unknown content and you have to make all them with equal height.

I know, flexbox can easily solve this problem, but tables rules can do it too.

Simply apply the display: table (or table-row) property to the container and the display: table-cell property to inner boxes. Take care to remove any float property (otherwise the table-cell property doesn't take effect).

HTML:

<div id="wrapper">
	<div id="div1"></div>
	<div id="div2"></div>
	<div id="div3"></div>
</div>

CSS:

[code]

#wrapper {
display: table;
}
#wrapper div {
display:table-cell;
}
[/code]

See the Pen Equal height boxes by Massimo Cassandro (@massimo-cassandro) on CodePen.

Case 2. Simple old-style layout

This one is a more outdated example, but I think you might need to deal with it, as I did recently.

Some months ago I received a graphic layout very similar to the scheme below. It needed to be compatible with IE8, and I found that the best way was to use CSS table rules:

See the Pen table display #3: old-style layout by Massimo Cassandro (@massimo-cassandro) on CodePen.

Case 3. Responsive layout with content choreography

The previous example leads us to a new topic: is it possible to build a responsive layout with CSS table rules?

Not only is possible, but we can also perform some content choreography tasks.

We have already seen how changing the display property from block totable-cell of two divs can change their arrangement from vertical to horizontal.

Add to this the fact that an element with the table-header-group property is brought to the top of a table layout. In the same way, table-footer-group elements are brought to the bottom and so on. This can be unexpectedly useful when reformatting responsive layouts.

In the pen below, the header element exchanges his position with the nav element on window resize, simply changing its display property to table-header-group.

HTML:

<div id="wrapper">
	<nav></nav>
	<header></header>
	<!-- rest of code -->
</div>

CSS:


@media (min-width: 48em) {
    #wrapper {
        display: table;
    }
    header {
        display: table-header-group;
    }
}

A similar behavior occurs for the footerand the #banner2 div.

Here is a scheme of the layout: on the left the default, mobile version, and on the right the desktop version:

And this is a running demo:

See the Pen display: table layout by Massimo Cassandro (@massimo-cassandro) on CodePen.

http://codepen.io/massimo-cassandro/pen/JovXXz/

For more info about this argument, take also a look at:

Conclusion

CSS table display properties are an under-rated and valuable solution for both big and little layout challenges.

While I may not personally choose to use them to build complex layouts, they can certainly solve many difficult problems related to portions of the layout.

Continue reading this article on SitePoint

The

#row {
   display: table-cell;
}

part in the demo for the wide screen seems to be redundant. All it does is wrapping the whole “main content” + #right_col structure in an anonymous single-cell table box, but it works just fine with the usual display:block because two contiguous table-cells already form an anonymous table box. So the outer single-cell table structure doesn’t add anything to it.

1 Like

That’s a good point, @SelenIT2. That display property could create other issues, so if it doesn’t have to be there…

Fixed. Thanks

I used to deploy flexbox in all my design work. Apple dropped support for flexbox in iOS 9, so I’ve had to replace it with CSS tables that do exactly the same job. My stylesheets haven’t changed much as a result.

I’ve included a sample of how flexbox and iOS 9 don’t play together. I’ve reported the problem to Apple but don’t expect it to get fixed any time soon.

I have to admit, although I’ve known about the CSS table and table cell properties, I’ve never used them.

Every time I see an article like this one I say to myself “Dude! So true! You gotta try it man!”, but I’m so used to floats and now doing things with Flexbox that this technique is left behind.

Nonetheless, article is bookmarked just in case :smile:

Nice read Mr. Massimo Cassandro.

Thanks Ricardo.

I also prefer to use floats or flexbox normally, but there are cases in which this technique becomes really useful

For equal height boxes, you said that “Take care to remove any float property”. Can you please explain why floats cause problems ? Here is an example where I did not remove floats http://codepen.io/rags4developer/pen/reqgNd.

Perhaps that is because there were none to remove. :mask:

Though, if you are actively seeking something to remove
you could take a stab at the “clear:both” here…

#footer {
  clear: both;
}

coothead

1 Like