Balancing content with Flexbox
One of the cool things we can do with Flexbox is to balance the text and images as if they were in a two-cell table. It should be possible to do so with images but instead we'll simulate two cells with the code below. I normally don't do this but in this case I will use CSS to populate the first div
element with the appropriate image.
<div class="column">
<figure class="flex">
<div></div>
<div>
<h3>Chrome Canary</h3>
<p>I install both Canary and Release versions to
make sure that the code I'm working on works in
my target browsers</p>
<p>I install both Canary and Release versions to
make sure that the code I'm working on works in
my target browsers</p>
<p>I install both Canary and Release versions to
make sure that the code I'm working on works in
my target browsers</p>
</div>
</figure>
</div>
The CSS is where all the magic happens. I've broken in into different sections. In the first section we define our layout. In particular:
- We define the element with class
flex
to have display flex - In odd children we change the default mode for flex to display elements in reverse order. This will display the image on the right side and the text on the left
- The first
div
child uses background attributes to manipulate the image. This is not really doable with images inserted using theimg
tag - The last
div
child will take twice the space of the first one
.flex {
margin: 0;
display: flex;
border: 5px solid #333;
margin-bottom: 2rem;
}
.flex:nth-child(odd) {
flex-direction: row-reverse;
}
.flex div:first-child {
flex: 1;
background-size: cover;
background-position: center;
}
.flex div:last-child {
margin: 2rem;
flex: 2;
}
In the second block of CSS we do some formatting for the text content of each section. The last paragraph, .flex p:last-of-type
has an additional rule to eliminate the bottom margin; this makes sure the empty bottom margin of that element doesn't add to the total height of the text.
.flex h3 {
font-size: 1.5rem;
margin-top: 0;
font-weight: 400;
}
.flex p {
font-size: 1rem;
line-height: 1.4;
font-weight: 400;
}
.flex p:last-of-type {
margin-bottom: 0;
}
This section adds the images as background images to the empty first div of each figure. I don't particularly like using background images because they make it harder to share and to work with outside of CSS.
For this kind of project working with images using the img
tag on the page doesn't produce the same effect. Using background-size: cover
is different than making the image fluid using percentages for width.
For each of the children of .flex
we add a background image to the first div
children. It can be the same image or a different one like we've done in this case.
.flex:nth-child(1) div:first-child {
background-image: url("images/chrome-canary_128x128.png");
}
.flex:nth-child(2) div:first-child {
background-image: url("images/chrome_128x128.png");
}
.flex:nth-child(3) div:first-child {
background-image: url("images/firefox-developer-edition_128x128.png");
}
.flex:nth-child(4) div:first-child {
background-image: url("images/firefox_128x128.png");
}
The final section of our CSS is a media query to accommodate smaller form factors and avoid the image looking ugly on iPhones and other smaller form factors. We accomplish this by changing the layout from horizontal to vertical (flex-direction
changes to columns
).
@media screen and (max-width: 600px) {
.flex { flex-direction: column; }
.flex div:first-child { min-height: 200px; }
.flex:nth-child(odd) {
flex-direction: column;
}
}
The idea is to create a consistent layout for images and text. We can use this as the index page for a magazine or the starting point of additional experiments using Flexbox beyond gallery displays.
Hat tip to Dudley Storey for the original idea.