CSS3 flexboxes: Holy grail layout example with flex-wrap for multiline
If the width is too small, then we get responsive design with flex-wrap and min-width (without media queries)
HTML
<div id="body">
<header>
header lorem ipsum
</header>
<div id='main'>
<article>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello<br/>Hello</article>
<nav>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</nav>
<aside>Related:<br />...</aside>
</div>
<footer>
footer lorem ipsum
</footer>
</div>
CSS
* {
border: 2px solid black;
padding: 2px
}
#body {
min-width: 220px;
background-color: yellow;
padding: 10px;
}
header,
footer {
display: block;
text-align: center;
margin: 5px 0;
background-color: black;
color: white;
}
#main {
display: flex;
flex-wrap: wrap;
}
article {
order: 2;
flex: 100 1 auto;
background-color: #afa;
min-width: 200px;
}
nav {
order: 1;
background-color: #aaf;
flex: 1 100 100px;
}
aside {
order: 3;
background-color: #faa;
flex: 1;
}
JavaScript
// The problem with this approach is that sidebars need to have non-zero flex to stretch to the outer container's width when in multiline mode (flex-wrap).
// However this implies that sidebars will also grow when there's a lot of space available for distribution.
// A solution could be to add huge flex-grow and tiny flex-shrink for the article, and the opposite (tiny flex-grow and huge flex-shrink) for the sidebars.
// NOTES:
// 1. <article> is before <nav> in the markup, but we order it visually using 'order'.
// 2. We get same-height containers for free, which was impossible without resorting to JavaScript, or required setting explicit heights on the containers. Now, on wide screen, all three columns will get the height of the highest one!
// 3. We get a responsive design without resorting to media-queries -- all we need is flex-wrap on the parent, and min-width and non-zero flex for the items.