One common issue in responsive design is the “odd man out” problem. Laying out a series of elements of approximately equal size is easy when there’s enough room:
But the moment the browser window narrows, the last element drops off the edge and is left hanging by itself.
Ideally, we want any elements pushed onto a new line to take up the same amount of space as those that remain above them, creating a stronger and more cohesive design:
That’s exactly the kind of problem flexbox was built to solve. Let’s say we have a gallery of images with the same aspect ratio in a <header>
element:
<header>
<div><img src="image1.jpg" alt></div>
<div><img src="image2.jpg" alt></div>
…
</header>
Then we can craft the following CSS (ignoring older flexbox syntaxes, for the sake of clarity):
header {
font-size: 0;
display: flex;
flex-flow: row wrap;
}
header > * {
flex: auto;
width: 200px;
}
header > * img {
width: 100%;
height: auto;
}
As you can see when you resize your browser window while looking at the example above, this very neatly solves the layout problem: an image pushed into a new row becomes the width of those above it. If that image is joined by another as the window narrows, they split the difference in the space that is now shared between them.
You might think of the width
for the <div>
elements in the CSS as working like min-width
: the moment that the containers, which must be at least 200px wide, cannot fit evenly on a row, one is pushed off to make room for the rest, with the new space redistributed.
This design pattern can work equally well for non-image elements with different heights and aspect ratios, as I’ll demonstrate in the next article.
Photographs by Jeremiah Wilson, licensed under Creative Commons.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/Kgofa