Grids in CSS3
The modern web is always changing, and this article is more than two years old.
By Tim Severien
In this article, we’ll take a look at some of the new features in CSS3 that make handling grids using HTML and CSS much easier. But first let’s discuss a little history of grids in HTML and CSS to get an understanding of what made them difficult.
A Short History of Grids
Years ago our layouts were a mess. Tables (meh) and frames (yuck) were the primary tools for creating multi-column layouts. They got the job done though.
Fast-forward to today. HTML and CSS have become very sophisticated and web design has gained both in terms of popularity and complexity. The old methods we’ve used for layout became outdated. However, a longstanding problem resurfaced: multi-column layouts.
To further complicate matters, we don’t have static-width pages any more. Everything is becoming responsive, so our preference is towards percentage-based column widths. Grids based on a fixed 960 pixel width simply won’t do – we need fluid grids.
The CSS2 spec solved columns with floats which caused a problem. To prevent the parent element from ruining your layout, we’d have to append a clearfix. That basically punches the parent in it’s face, tells it to wake up and recognize that the content stops exactly here. We’ve kind of accepted that, but many agree that it’s still a hack.
The inline-block method is less common, but still out there. An inline-block element respects text lines so that they naturally stack next to each other. When a line is full, it wraps to the next line – easy enough. But, because it respects text, it respects white spaces. That means you actually have to avoid white spaces between each element in the HTML. Inline-block was never meant for this and it doesn’t work that well either.
Out of these two, the method using floats is most reliable. That’s probably why it’s more popular in the first place. Still, after creating columns, we realize that the content is squeezed against each other and we need some padding. And that’s where the final problem arises: the box-model.
The box-model represents, in simple terms, the actual size of an element including its: height/width + padding + border-width. With margins, the box doesn’t gets bigger, simply pushes things away. So after setting a width of, lets say, 25%, the actual area of a box can actually be much larger, meaning there’s not enough space to put four elements in one row.
This cocktail of ‘problems’ has different solutions: negative margins, nested elements – I’ve seen it all. They all require either extra CSS or DOM in a hack-ish way. Lets face it, there’s no good CSS2-based solution for grids.
Today, however, CSS3 has decent support and the spec adds several new features specifically to use with grids. Which features help and how do we use them? Let’s take a look.
One of the problems that has been addressed is the extending nature of the box-model. The
box-sizing property can solve this by setting its value to
border-box. This shrinks the content so that the padding and border fits within the defined width.
Though this works great, we are still using floats and we still need the clear-fix. Besides, we can only use padding as spacing, margins are not done. That means there is no actual space between each block, but rather it’s content. While this is useful for many designs, but it still feels a little wrong.
- Firefox 1
- Chrome 1
- IE 8
- Opera 7
- Safari 3
width: calc(percent – spacing)
Another great option is using the
The ability to recalculate sizes client-side is a great option but, unfortunately, we still need the floats, and we need a negative margin on the column container too. Again, a good option, but it still feels weird.
- Firefox 4
- Chrome 19
- IE 9
- Opera ?
- Safari 6 (appears to be a little buggy)
Flexboxes are elements with specific configurable behavior – a little like tables. Did I really say that? Yes I did. The behavior of tables is actually pretty good, due to it’s ability to change itself according it’s contents. But, layouts are no longer built using tables, so the table tag isn’t an option.
At first, flex-box looks a little complex. There are many different properties that can be difficult to understand, especially for a non-english speaker like myself. Luckily, Chris Coyier wrote a great guide about flex-box that I can’t possibly improve.
Just like that! But… browser support is not great.
- Firefox 18
- Chrome 21
- IE 10
- Opera 12.10
- Safari 6.1
Even though CSS3 comes with many new features and fixes several longstanding issues, in my opinion, flexbox is the only hack-free candidate for creating flexible grids in CSS. Unfortunately though, browser-support for flexbox is “meh.” Nonetheless, the other alternatives do make it a little more semantic, so they are an improvement, and they have pretty good browser support.
Header image courtesy of http://commons.wikimedia.org/wiki/File:WLANL_-HannyB-_Grid.jpg