I will teach you how to use flexbox in practice — code included.
This example was developed in Chrome without browser prefixes, so check your browser support at Caniuse.com. Unless you need to support IE<11 or Safari<8, you’ll need no browser prefixes at all. If you need support for older browsers, use autoprefixers in your workflow and make workarounds for bugs listed at Flexbugs. You can also use @supports media query for achieving fallbacks for Firefox, Chrome, and Opera. Also, it’s possible to use Modernizr to detect when you need a fallback with flexbox.
Here’s a screenshot of the final product we are going to build, step-by-step.
Let’s get crackin’.
The basic DOM structure for all flexbox cases is as follows:
<section class="parent">
<section class="item"></section>
<section class="item"></section>
<section class="item"></section>
</section>
We have a parent element, which holds all the items, which will be flexed. Flexbox only affects the direct children of parent.
When you need vertically aligned items, use flex-direction: column
— for horizontal layouts, use flex-direction: row
.
display: flex
What this does is align the items of the parent in a row. I’ve attached JSBin’s about the progress.
Okay, so now we have block-level elements side-by-side. Now this is pretty bare-bones, so let’s add some more challenging content to the DOM.
Let’s make the elements flow on next row by adding the rule flex-wrap: wrap
to the parent. Hooray! We have a responsive (ish) design.
The layout isn’t exactly optimal yet, so let’s make the items fill the width on screen in a more sane way: Always fill 100% of the width, and use equal sizes for the items.
Let’s add flex-grow: 1
to let the items fill the width equally.
Let’s add text-align: center
to center all content inside each product. I also added some basic styling, including my favourite font: Titillium Web.
Let’s vary the content lengths a bit, since these are usually edited in administration by our customers. Wow, what the hell is going on here? How can we keep the items equal size?
Let’s add flex-basis: 0
to the flexbox in order to prevent the extra space around content. Let’s use the shorthand version, just type: flex: 1 1 0
(this is shorthand for flex-grow, flex-shrink and flex-basis combined).
So we have now written a responsive grid in just 4 CSS rules… Amazing!
The long h1’s are causing the images to misalign horizontally. There isn’t exactly one way to solve this — it’s partly an editorial issue. All we can do is to optimize our layout for specific content lengths. Let’s make our lives a bit easier by moving the product images as first element of each item.
Let’s complicate the DOM a bit:
Also, let’s add basic styling for those elements.
In order to use the flexbox-magic for each product, let’s tell them to display: flex
as well. But this time we want to keep them on top of each other, so let’s add flex-direction: column
to them as well. Add align-items: center
to make each direct DOM children of a product to align themselves on center.
Let’s set the product spec (ul) to display as flex as well (surprise!). In order to justify the two li’s at the and the beginning of the row, let’s add justify-content: space-between
.
margin-top: auto
to aside element to magically keep the buttons and specs at the bottom.Now we have a pretty neat layout — Check it out! I added some responsiveness to the image sizes with media queries.
The last items seem to behave erroneously (or at least we’re not used to this on layouts). Let’s add max-width: 400px
to flex items — now this is the same as the width of the image. I’ve also added a media query to change the max-width to 250px on below 1600px wide screens, but this is just a responsiveness trickery due to image resizing. I chose to add max-width instead of width so my boxes’ size (paddings and margins) will remain fixed.
Because of the max-width, we need to define a justify-content
for the parent .flex. The value depends on your personal opinion. I chose to center the parent’s items as it seems like a logical way. Be sure to try out space-between
and space-around
for this!
I couldn’t help myself to improve the colors and typography. I also added a flexbox navbar!
Here’s all the code for the flexbox-related stuff (everything else was just candy sprinkled on top of them).
and the HTML:
In no means this is a complete solution, there’s still some flexbox quirks you need to fix / make workarounds for. For example, what should we do with the last items? …Anyways I’ve fallen in love with flexbox. Especially justify-content
and align-items
which solve common problems, such as aligning grouped header items: brand, navigation and search with justify-content: space-between
. The syntax is pretty awesome too, and you can avoid the float bloat and position inquisition. One neat tip is to use a media query for screen widths and convert flex-rows to cols to make the site responsive really easily. This goes especially with React.js — you can use componentized flexbox and ensure browser support with autoprefixers.
Note: justify-content
and align-items
are a part of part of the CSS Box Alignment Module.
The easiest way to get started with flexbox is probably Bennett Feely's
Flexplorer.
For more practical flexbox solutions, I suggest to check out Zoe Mickley Gillenwater’s Enhancing Responsiveness /w Flexbox.
If you’re more into reading, check out this book: Hardboiled Web Design.
I haven’t used flexbox extensively, but I’ve noticed a pattern where your UI has rows and cols alternating — This happened to the product page as well.
Flexbox isn’t meant for whole page layouts — There’s an upcoming standard called CSS Grid. A W3C Candidate Recommendation was released on 29th of September, 2016.
CSS is evolving all the time — So let us evolve on how we solve common UI design patterns.
See what we have to offer - Careers