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 block, inline and 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 flex property.

That’s it! With that simple bit of code we have a left navigation sidebar, a middle content section and a right sidebar. The nav and aside elements each have a width of 12em and the section element has a fluid width that flexes between the nav and aside. Notice we didn’t even need to set any properties on the section element.

So what’s behind the flex values?

It’s easy enough to see how this works, but WHY is it working? Why is the section flexing its width between the nav and aside elements? Well, the flex property is actually shorthand for flex-grow, flex-shrink and flex-basis.

So this:

Is shorthand for this:

Setting flex-grow and flex-shrink to 0 prevents the elements from, you guessed it, growing and shrinking. And setting flex-basis to 12em defines the width.

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.

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.

CodePen example

Kyle Pennell
Kyle Pennell is a marketer and writer with a variety of technical chops (JavaScript, Google Sheets/Excel, WordPress, SEO). He loves clear and helpful copy and likes automating things and making web apps (mostly maps). Found at and many other digital spaces