Solving the Holy Grail Layout
Searching for the elusive Holy Grail of CSS layouts has lead to many clever solutions, but never has there been a single solution that doesn’t involve hacks or drawbacks. Tables, divs with
table-property displays, and absolutely positioned divs are some of the ways we’ve accomplished the Holy Grail layout in the past. With the introduction of Flexbox though, we can end our search for the Holy Grail of web layouts. With the power of CSS3, the once highly sought after solution has been found.
The Flexible Box Layout Module, more commonly known as Flexbox, confronts many layout issues head-on, including the Holy Grail layout. So just what is the Holy Grail layout?
The Holy Grail layout is simply a multiple (usually 3) column layout with fixed widths for the first and last columns and a fluid width for the center column. Setting explicit widths on the outer columns is what makes the layout tricky, because we can’t calculate the width of the center column (well, technically we can using the CSS
calc property, but we’ll save that for later). If we just used percentages for the outer columns, we could easily achieve a fluid layout. But we’re after the Holy Grail, remember?
Ending the Holy Grail search
To start off with, we have to set the
display property to
flex on a containing element. Just like we have
inline-block values for the
display property, we now have
flex. For the sake of a simple example, we’ll just use the body as our only containing element.
This now sets us up to start using the different Flexbox properties. There are about 13 different properties available that you can check out in full in the W3C spec, but all we need for our layout is the
<aside></aside>[/html] [css] html,
flex: 0 0 12em;
That’s it! With that simple bit of code we have a left navigation sidebar, a middle content section and a right sidebar. The
aside elements each have a
12em and the
section element has a fluid width that flexes between the
aside. Notice we didn’t even need to set any properties on the
So what’s behind the
It’s easy enough to see how this works, but WHY is it working? Why is the
section flexing its
width between the
aside elements? Well, the
flex property is actually shorthand for
So this:[css] flex: 0 0 12em;
Is shorthand for this:[css] flex-grow: 0;
0 prevents the elements from, you guessed it, growing and shrinking. And setting
12em defines the
The good news?
You can use Flexbox today in the latest versions of most modern browsers.
The bad news?
We’re still a ways away from being able to rely on Flexbox in a wide variety of browsers. The syntax has changed several times since it first came out, so to get support in IE10 and other older browsers, we have to use some different vendor prefixes.[css] display: -moz-box; /* OLD: Firefox (buggy) */
display: -ms-flexbox; /* MID: IE 10 */
display: -webkit-flex; /* New: Chrome 21+ */
display: flex; /* NEW: Opera 12.1, Firefox 22+ */
None of the properties work in IE9 and below and Safari and Firefox have varying levels of support. Our example above, for instance, renders a 3 row layout in Safari 6. However, we can always provide float and width fallbacks for older browsers.