Although the syntax might be initially confounding, flexbox1 lives up to its name. It creates intelligent boxes that are stretchable, squeezable and capable of changing visual order. It provides simple solutions to layout paradigms that CSS has always struggled with: vertical centering and equal heights. Flex items are truly accommodating and a pleasure to work with.
Flexbox Layout(Flexible Box) module (currently a W3C Last Call Working Draft) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”).
The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.
Flexbox truly shines with HTML5 web applications. Most web apps consist of a series of modular, reusable components. You can use flexbox for those bits of layout that induce headaches and that depend on brittle CSS hacks to work. Small modules work very well with flexbox, and you can use floats and other tools for broader sections of the layout.
I’m using flexbox in a big way for a web app that I’m currently working on, and I am very pleased with how it handles layout and box calculations intelligently. I’d like to share some demos and examples of this — any feedback would be appreciated.
This article presumes that you have working knowledge of flexbox. A wealth of information is available online. Keep in mind that the specification has undergone several changes over the years.
There are three versions of flexbox, largely differentiated by the syntax changes between 2009 and 2012:
- The new syntax is in sync with the current specification (e.g.
- The tweener syntax is an unofficial syntax from 2012, adopted only by IE 10 (e.g.
- The old syntax is from 2009 (e.g.
Browsers That Support the New Syntax
- Unprefixed: Chrome 29+, Firefox 28+, IE 11+, Opera 17+
-webkit-prefix for Chrome 21+, Safari 6.1+, Opera 15+
Note: Old versions of Firefox (22 to 27) support the new syntax minus the
flex-flow properties. Opera (12.1+ and 17+) supports flexbox without vendor prefixes, but intermediate versions 15 and 16 require vendor prefixes.
- Unprefixed: Android 4.4+, Opera mobile 12.1+, BlackBerry 10+, Chrome for Android 39+, Firefox for Android 33+, IE 11+ mobile
-webkit-prefix for iOS 7.1+
Almost all of the browsers mentioned above have old versions that support a prior variant of flexbox, minus some properties such as
flex-flow (the latter of which is a shorthand for the
flex-wrap properties). By avoiding
flex-wrap (and, therefore, using flexbox in multi-line layouts), we get amazing browser support, merging the old and current syntax.
Browsers That Support the Tweener Syntax
Desktop and touch: IE 10 (with
-ms- vendor prefix)
Browsers That Support the Old Syntax
All of these desktop and touch browsers require the
-webkit- vendor prefix (except for Firefox, which needs the
Desktop: Firefox 2 – 21, Chrome 4 – 20, Safari 3.1 – 6
Touch: Android 2.1 – 4.3, iOS 3.2 – 6.1, UC browser 9.9 on Android, BlackBerry 7
For modern browsers that auto-update (i.e. desktop Chrome, Firefox, IE and Opera), the new syntax works out of the box.
Browsers That Don’t Support Flexbox
Desktop: Old versions of IE (9) and Opera (12)
Touch: Opera Mini
You can also use the following tools to get the best browser support via vendor prefixes:
With this general-purpose tool for vendor prefixing, you write the CSS or use a preprocessor, and it does what’s needed.
- Sass flexbox mixins6
The LESS mixin comes in two flavors: with7 and without8 the tweener syntax for IE 10.
I would recommend Autoprefixer from among these. I haven’t experimented with the other preprocessor-specific solutions and welcome feedback if you have. Note that if you’re using a mixin with a helper library (such as Bourbon or Compass for Sass, Nib for Stylus or LESS Hat for LESS), it comes built in with vendor-prefix support for flexbox.
With a tool like Autoprefixer, you actually get great support across the board for flexbox, save for IE 9 and Opera Mini. Of course, you’ll need to thoroughly test your app across all browsers to make sure that the different syntaxes hold up.
Let’s look at a few good use cases for flexbox with web app modules.
1. Unknown Number Of Children Within A Parent
Use case: My app has search filters. The number of search filters depends on whether a user is signed in. Anonymous users see two filters (“Popular” and “Latest”), while signed-in users see four (“Starred” and “Favorites”, additionally).
Issue: I’d like the styling to accommodate both options, without any change to the CSS.
Discussion: You’d generally have an
if statement in your template to handle the state for signed-in users. If you were using floats for the layout, you’d have to set a width of 50% for the filters for anonymous users and a width of 25% for the filters for signed-in users.
Solution: With flexbox, you can just make the parent a flex container by declaring
display: flex and give the children the property of
flex and a value of
1, which would make each of the children take up equal widths inside their parent. So, the CSS would remain the same no matter the view. Remember that the
flex property is a shorthand for
2. Inputs With Icons
Use case: I wish to add meaningful icons to my form inputs.
Issue: I want an elegant, flexible solution that works without having to declare unnecessary heights and widths on the elements.
Discussion: This one’s a classic problem. Different front-end frameworks approach this differently, generally using
display: table-cell or absolute positioning.
Solution: Here’s the flexbox way. All we need to do is wrap the input and the icon besides it in a parent with
display: flex. Then, we apply
flex: 1 to the input, so that it takes up the remaining space of the parent, minus the width of the icon.
Demo (using Font Awesome font icons via the CDN for convenience):
3. Visual Order
Flexbox can be used to change the visual order of a document, leaving speech order and navigation intact16 according to the document’s source order. Our job as developers is to responsibly use the immense power of flexbox’s ordering mechanisms.
In fact, we can structure our documents with a source order that is appropriate to assistive technologies such as screen readers (for example, putting the sidebar before the main content in the source order), and use flexbox to simply alter the visual order for those who enjoy the benefits of a graphical user interface (by placing the sidebar on the right of the main content via the
flex-direction property). Let’s look at this in detail.
A. Visual Order Independence With Flex-Direction
Use case: I have a sidebar positioned to the right of the main content section. On small screens, I want the sidebar to be at the top of the main content, reversing the order.
Discussion: Flexbox is agnostic about the order in a layout. This makes it a miraculous tool for responsive layouts. We can do this in two ways: using the
flex-direction property or the
order property. Let’s look at the first option here.
Solution: Let’s build the layout with the sidebar as the first section in our markup. This is logical for two reasons: It adheres to the principle of a mobile-first layout, and it is beneficial to screen readers because the sidebar links are first in the source order. Let’s declare
flex-direction: column on the parent (because
row is the default). In our media query for large screens, we’ll change
row-reverse, which solves our issue.
As a bonus, we’ll throw in a fixed-width sidebar (which is always 180 pixels on large screens and full width on mobile).
B. Visual Order Independence With the Order Property
Our use case and issue are the same as in the example above.
order property provides more fine-grained control over the visual order than
Solution: We’ll declare
flex-direction: column on the parent to stack both the columns on mobile. Then, on a
min-width media query, we’ll change the
row, which will show the sidebar on the left and the main content on the right. To reverse the order, we simply declare
order: 1 on the main content and
order: 2 on the sidebar!
C. Toggling Ascending and Descending Order
Use case: I want to show a list of the five highest-paid actors in Hollywood in 2013, allowing their order to be toggled.
Issue: I want to do this in pure CSS and I can’t explain why, but I’m not sure it’s even possible.
Solution: We’ll add a checkbox input with a label, which we’ll use to toggle the order from lowest to highest. Below this, we’ll add a list of the actors. Using the
:checked CSS pseudo-class selector, we select the immediate
ul sibling of the checkbox in order to reverse the direction of the unordered list’s items (by using
flex-direction: column-reverse). It’s weird but it works perfectly, unless you’re using a screen reader or the keyboard for navigation. In the demo below, check the box and use the keyboard to navigate to see the implications of this. The specification mentions that the
order property affects neither
tabindex nor non-visual media such as speech.23 Therefore, I wouldn’t recommend this solution for a real-world project. Perhaps it would come in handy in a quick prototype.
Note: Firefox has a bug24 in its current version (version 34 on Ubuntu and Mac OS X, version 33 on Windows) that results in the
tabindex complying with the flex order and not the source order. You can look at the test cases25 for the CSS Accessibility Community Group.
4. The Comment Module
Use case: I have a typical comment module, with an image to the left and content on the right. The image avatar is always the same width and height (i.e. it’s not responsive).
Issue: I’m using flexbox, but the content overlaps the image:
If you set
auto on the image, you will end up with the following:
Discussion: This example is similar to the “Inputs with icons” demo. However, we can use it to discuss the
flex-shrink property, which is very handy in some cases.
display: flex to the parent wrapper. You will notice that the text overlays the avatar image (or that the avatar image is very small, as in the image above). To overcome this, you can declare
flex-shrink: 0 on the image, which ensures that it will not shrink to accommodate the width of other flex items. The alternative is to apply the
flex: 1 shorthand to the comment text. In this case, you wouldn’t need
flex-shrink: 0 on the avatar. In general, the specification recommends the flex shorthand method29, but it’s good to know about the
flex-shrink standalone property as well.
5. Complex Menus
Use case: My app has a menu that includes a search and sort widget. It’s a mix of buttons, inputs, icons and text.
Issue: I’m worried about the layout breaking across different screen sizes.
Discussion: This is a perfect use case for flexbox. We have some items with a fixed width (although we don’t need to declare these widths) and other items that need to fill up the rest of the screen’s width.
Solution: We can use flexbox to get vertical centering and a flexible search-and-sort module with relatively little code.
Demo (using Font Awesome via the CDN for convenience):
Issue: On large screens, I want the cards to be inline. The height of cards in a line should be the same, although the markup won’t include rows that wrap sets of cards. The “See More” button should always be positioned at the bottom of the card.
Discussion: We can look at additional properties in the flexbox module, such as
margin: auto to intelligently handle spacing.
Solution: Flexbox provides an incredible solution to a mammoth CSS issue: equal heights. In fact, flexbox is so flexible that it allows cards in a row to be of equal heights, even though there are no wrapper row divs around a set of cards. It also allows the “See More” buttons to appear as if they are absolutely positioned at the bottom of the card, using a nifty
margin: auto trick.
Demo (using the
flex-wrap property, which does not work in some older browsers):
Flexbox could be the perfect fit for a hybrid web app whose target audience is on smartphones with the latest browsers. In fact, some popular front-end frameworks use flexbox, including ZURB’s Foundation for Apps40 and Ionic41.
If your app requires only modern browser support, welcome aboard! Using a tool like Autoprefixer eases the transition into the world of flexbox, with its multiple versions and syntax soup. While flexbox pairs well with floats, it can also replace it and do things that no other layouting model currently can, including inline blocks, table displays and absolute positioning. The “CSS Grid Layout Module42” is intended to replace workarounds and hacks such as floats, but it’s at a nascent stage, with poor browser support43. Some day in the future, I dare to dream that CSS grids and flexbox will be all we use to build intuitive user interfaces, because they play well together.
It takes a while to have your “Ah-ha” moment with flexbox, because it involves unlearning what you already know about CSS layouting. Once you speak the flexbox language fluently, your process of designing responsive apps will become effortless and your style sheets will get leaner.
Helpful Links and Resources
- “Designing CSS Layouts With Flexbox Is as Easy as Pie44,” David Storey, Smashing Magazine
This in-depth article provides great solutions using flexbox for real-world CSS problems. It includes tables that map the differences between the old and new specifications.
- “A Complete Guide to Flexbox45,” Chris Coyier
This valuable article on CSS-Tricks lists the properties related to flex containers (i.e. parents) and flex items (i.e. children) side by side. It’s one of the best references for working on a layout that incorporates flexbox.
- “Flexbox Adventures46,” Chris Wright
This thorough article analyzes the
flex-shrinkproperties, information that is hard to find online. Chris Wright provides helpful examples and has a cautionary view of flexbox, suggesting progressive enhancement for small UI components.
- “Are We Ready to Use Flexbox?47,” Nick Salloum, SitePoint
This beginner’s introduction to flexbox also covers possible solutions to the profusion of vendor prefixes for all versions of the syntax.
- Flexy Boxes48
This “flexbox playground and code generator” covers all of the flexbox properties, with all versions of the syntax.
- “Flexbox Nav Bar With Fixed, Variable, and Take-Up-The-Rest Elements49,” Chris Coyier
This entire article is devoted to the traditional fixed-plus-fluid CSS layouting nightmare — in this case, for a navigation bar. It reiterates how flexbox trumps all other layouting methods.
- “Solved by flexbox50,” Philip Walton
Philip Walton makes a compelling case for using flexbox, with demos for grids, sticky footers, the media object and more.
- “Flexbugs51,” Philip Walton
Github repo by Philip Walton for cross browser flexbox bugs and workarounds
- “Using CSS Flexible Boxes52,” Mozilla Developer Network
This dives into the details while covering the edge cases and quirks of flexbox. You’ll find the so-called Holy Grail layout done in flexbox.
- The Ultimate Flexbox Cheat Sheet53
Highly recommended, and written for humans.
(ds, il, al)
- 1 http://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
- 2 http://css-tricks.com/snippets/css/a-guide-to-flexbox
- 3 http://caniuse.com/#search=flexbox
- 4 http://css-tricks.com/using-flexbox
- 5 https://github.com/postcss/autoprefixer
- 6 https://github.com/mastastealth/sass-flex-mixin
- 7 https://gist.github.com/kenstone/5460000
- 8 https://gist.github.com/jayj/4012969
- 9 http://css-tricks.com/snippets/css/a-guide-to-flexbox
- 10 ‘http://codepen.io/imohkay/pen/vENEEe/’
- 11 ‘http://codepen.io/imohkay’
- 12 ‘http://codepen.io’
- 13 ‘http://codepen.io/imohkay/pen/QwjwwY/’
- 14 ‘http://codepen.io/imohkay’
- 15 ‘http://codepen.io’
- 16 http://www.w3.org/TR/css3-flexbox/#flow-order
- 17 ‘http://codepen.io/imohkay/pen/JoYoRE/’
- 18 ‘http://codepen.io/imohkay’
- 19 ‘http://codepen.io’
- 20 ‘http://codepen.io/imohkay/pen/VYvYKM/’
- 21 ‘http://codepen.io/imohkay’
- 22 ‘http://codepen.io’
- 23 http://www.w3.org/TR/css3-flexbox/#order-accessibility
- 24 https://bugzilla.mozilla.org/show_bug.cgi?id=812687
- 25 http://sprungmarker.de/wp-content/uploads/css-a11y-group/css-a11y-flexbox.html#newspec
- 26 ‘http://codepen.io/imohkay/pen/QwjwKP/’
- 27 ‘http://codepen.io/imohkay’
- 28 ‘http://codepen.io’
- 29 http://www.w3.org/TR/css-flexbox-1/#flex-components
- 30 ‘http://codepen.io/imohkay/pen/OPyPbo/’
- 31 ‘http://codepen.io/imohkay’
- 32 ‘http://codepen.io’
- 33 ‘http://codepen.io/imohkay/pen/QwjwGP/’
- 34 ‘http://codepen.io/imohkay’
- 35 ‘http://codepen.io’
- 36 http://www.google.com/design/spec/components/cards.html
- 37 ‘http://codepen.io/imohkay/pen/PwPwWd/’
- 38 ‘http://codepen.io/imohkay’
- 39 ‘http://codepen.io’
- 40 https://github.com/zurb/foundation-apps
- 41 http://ionicframework.com
- 42 http://www.w3.org/TR/css-grid-1
- 43 http://caniuse.com/#search=grid
- 44 http://www.smashingmagazine.com/2013/05/22/centering-elements-with-flexbox
- 45 http://css-tricks.com/snippets/css/a-guide-to-flexbox
- 46 http://chriswrightdesign.com/experiments/flexbox-adventures
- 47 http://www.sitepoint.com/are-we-ready-to-use-flexbox
- 48 http://the-echoplex.net/flexyboxes
- 49 http://css-tricks.com/flexbox-nav-bar-fixed-variable-take-rest-elements
- 50 http://philipwalton.github.io/solved-by-flexbox
- 51 https://github.com/philipwalton/flexbugs
- 52 http://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
- 53 http://www.sketchingwithcss.com/samplechapter/cheatsheet.html
- 54 https://lincolnloop.com/blog/introducing-flexbox-fridays/