Holy Grail

For many years, web developers sought to achieve this holy grail of web interfaces:

Holy grail interface pattern

The holy grail layout has a header at the top, a footer at the bottom, sidebars on the left and right, and a scalable main content area in the center. This layout was elusive in the early days of the web; thus its name. But Flexbox has eliminated most of these perils.

A flex parent only handles one-dimensional flow. This layout requires control over two dimensions, which you can achieve by nesting a horizontal flex parent inside a vertical one. You might start by making the body element the vertical parent:

html
css
preview

You see the header and footer, but where's the middle row? It has no content, so it has no size. You want the middle section to absorb any space that hasn't been taken up by the header and footer. Try setting the middle section's flex-grow property.

By itself, setting flex-grow has no impact. The parent must first have extra space before it can distribute it, and elements don't have extra vertical space unless you take control of their height. Making the body fill the viewport with min-height does the trick:

html
css
preview

That takes care of the vertical parent. The middler will serve as the horizontal parent. Its children will be a couple of aside elements for the left and right sidebars and a main element:

html
css
preview

The middler's properties show that it is both a flex child and a flex parent. The main section must expand to absorb all the extra space. Try setting its flex-grow property.

After you get main to expand, add some content into the left sidebar. You will see the left sidebar expand and take away real estate from the main element. Probably the sidebars should have a fixed width that isn't influenced by the content. The flex-basis property is your vehicle for assigning this fixed width:

html
css
preview

Try adding content to the sidebars now. You will see the content wrap instead of expand the element.

Try adding content to the main element. You will find that the main element expands and takes away space from the sidebars. The problem is that the main elements flex-basis is auto, which means it will puts its baseline size from the element's width value. The width is also set to auto by default, which means the browser will calculate it to fit around the content to the degree possible. You can fix this by setting the basis to 0:

html
css
preview

Try adding content to the main element now. You will find the layout to be stable.

As you add content, you are disturbed by how the text runs right up to the edge of its parent elements:

html
css
preview

All five cells of the layout need some padding to allow the text to breathe:

html
css
preview

That's much better.