Harnessing Flexbox For Today’s Web Apps

About The Author

Karen Menezes works towards an open, adaptive web that is accessible to all. She has an inexplicable love for CSS and responsive user interfaces. In her … More about Karen ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 200,000+ folks.

Flex items are truly accommodating and a pleasure to work with. 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. It takes a while to have your “Aha!” moment with flexbox, because it involves unlearning what you already know about CSS layouting. But once you speak the flexbox language fluently, your process of designing responsive apps will become effortless and your style sheets will get leaner!

Although the syntax might be initially confounding, flexbox 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.

Chris Coyier sums up flexbox nicely:

"The 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:

  1. The new syntax is in sync with the current specification (e.g. display: flex).
  2. The tweener syntax is an unofficial syntax from 2012, adopted only by IE 10 (e.g. display: -ms-flexbox).
  3. The old syntax is from 2009 (e.g. display: box).

Browser Support

Let’s look in detail at which browsers support which syntax, courtesy of Can I Use.

Browsers That Support The New Syntax

Desktop:

  • Unprefixed: Chrome 29+, Firefox 28+, IE 11+, Opera 17+
  • Prefixed: -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-wrap and flex-flow properties. Opera (12.1+ and 17+) supports flexbox without vendor prefixes, but intermediate versions 15 and 16 require vendor prefixes.

Touch:

  • Unprefixed: Android 4.4+, Opera mobile 12.1+, BlackBerry 10+, Chrome for Android 39+, Firefox for Android 33+, IE 11+ mobile
  • Prefixed: -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-wrap and flex-flow (the latter of which is a shorthand for the flex-direction and 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 -moz- prefix).

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

If you’re getting intimidated by the number of vendor prefixes and changes in syntax, have a look at Chris Coyier’s recommendation.

You can also use the following tools to get the best browser support via vendor prefixes:

  • Autoprefixer With this general-purpose tool for vendor prefixing, you write the CSS or use a preprocessor, and it does what’s needed.
  • Sass flexbox mixins
  • Less. The LESS mixin comes in two flavors: with and without 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 flex-grow, flex-shrink and flex-basis.

Demo:

See the Pen Flexbox: Parents with an unknown number of children by Karen Menezes (@imohkay) on CodePen.

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):

See the Pen Flexbox: Inputs with icons by Karen Menezes (@imohkay) on CodePen.

3. Visual Order

Flexbox can be used to change the visual order of a document, leaving speech order and navigation intact 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 order or 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.

Issue: I don’t want to use JavaScript or a CSS hack to change the visual 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 flex-direction to 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).

Demo:

See the Pen Flexbox: Sidebar with source order independence using flex-direction by Karen Menezes (@imohkay) on CodePen.

B. Visual Order Independence With The Order Property

Our use case and issue are the same as in the example above.

Discussion: The order property provides more fine-grained control over the visual order than flex-direction.

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 flex-direction to 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!

Demo:

See the Pen Flexbox: Sidebar with source order independence using order by Karen Menezes (@imohkay) on CodePen.

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.

Discussion: This is a simple no-JavaScript demo to show how powerful flexbox can be. Perhaps a bit impractical and crazy, but let’s see if there’s a way.

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. 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 bug 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 cases for the CSS Accessibility Community Group.

Demo:

See the Pen Flexbox: Toggling a list’s order by Karen Menezes (@imohkay) on CodePen.

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:

flexbox-comments-overlap

If you set max-width to 100% and height to auto on the image, you will end up with the following:

flexbox-comments-max-width

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.

Solution: Apply 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 method, but it’s good to know about the flex-shrink standalone property as well.

Demo:

See the Pen Comments module with flexbox by Karen Menezes (@imohkay) on CodePen.

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):

See the Pen Flexbox demo: Search and filter by Karen Menezes (@imohkay) on CodePen.

6. Cards

Use case: I’m creating a card module for my app, based on the card component in Google’s material design documentation. The cards will stack on mobile.

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):

See the Pen Flexbox: Card module by Karen Menezes (@imohkay) on CodePen.

Conclusion

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 Apps (see also GitHub page) and Ionic.

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 Module” is intended to replace workarounds and hacks such as floats, but it’s at a nascent stage, with poor browser support. 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 “Aha!” 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.

  • Flexbox,” Sara Soueidan, Codrops This useful CSS reference guide includes a comprehensive documentation on all things flexbox.
  • Designing CSS Layouts With Flexbox Is as Easy as Pie,” 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 Flexbox,” 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 Adventures,” Chris Wright This thorough article analyzes the flex-grow and flex-shrink properties, 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?,” 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 Boxes 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 Elements,” 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 flexbox,” Philip Walton Philip Walton makes a compelling case for using flexbox, with demos for grids, sticky footers, the media object and more.
  • Flexbugs,” Philip Walton Github repo by Philip Walton for cross browser flexbox bugs and workarounds
  • Using CSS Flexible Boxes,” 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 Sheet Highly recommended, and written for humans.
  • A Visual Guide to CSS3 Flexbox Properties,” Dimitar Stojanov As the name indicates, this flexbox guide provides a quick visual reference, eliminating the need for lengthy explanations. Equally useful for beginners as well as advanced users, who need a handy resource while building flexbox intensive layouts.

Further Reading

Front page image credits: “Introducing Flexbox Fridays” by Joni Trythall.

Smashing Editorial (ds, il, al, mrn)