Flexbox: The Most Powerful CSS that No One is Using

What if I told you that you can vertically center, match height, and reorder HTML using only CSS? Amazing, right?

Now, what if I told you that this CSS is not supported in IE9 and only partially supported in IE10?

*cue Price is Right losing horn*

 

Flexbox is a very powerful set of CSS rules that can quickly accomplish all of the aforementioned tasks, yet UI developers still fret over them in every project. There is a pure CSS solution to some of the largest UI problems, and most developers feel as if they can’t use it due to incomplete IE support. We have a dollar in our pocket, but we are still counting pennies at the cash register. Flexbox should not be doomed to a life of freelance and side projects – let’s use it in production!

If you’re interested, here is a great CSS Tricks article that explains flexbox rules in depth. Read it here.


 

Method 1: Modernizr

Modernizr is a JS tool that we use in our projects here at BrainJocks, and it’s perfect for this situation. Modernizr looks at the browser that you’re currently using and appends classes to the <html> element based on which CSS features are supported and which ones aren’t. In our case, we’re interested in the classes .flexbox and .no-flexbox. If we inspect a page in IE11 and then in IE9, we will see the following:

IE11:

2015-10-26_1614

IE9:

2015-10-26_1614(1)

 

That certainly makes our lives easier. Now, to use flexbox on an element, we can target the element under .no-flexbox and under .flexbox. This method will allow us to give an element completely different styles depending on whether or not the user’s browser supports flexbox, therefore enabling us to style them perfectly for each scenario. I used this recently for a component that showed rows of product images in an unordered list. For non-flexbox browsers, I floated the list items and gave them different percentage widths based on the screen size (a common practice, but difficult to write and maintain). With this method, you also have to figure out the margins and determine which elements are at the end of the rows using nth-child. For flexbox browsers, I was able to accomplish the same thing with a lot less code (not necessarily fewer lines of code, but more on that in a minute). The modern Chrome version looks like this:

ul {
     display: flex;
     flex-wrap: wrap;
     align-content: space-between;
     li {
          flex-basis: 100%;
          @media only screen and (min-width: @screen-xs-min) {
               flex-basis: 48%;
          }
          @media only screen and (min-width: @screen-sm-min) {
               flex-basis: 32%;
          }
     }
}

This code says make the <ul> a flex container, wrap the items inside into rows, put some space between the items, and then change the minimum width of the items based on screen size. This will make the items one-up on small phones, two-up on large phones, and three-up on tablets. No margins or nth-childs in sight!

 

Method 2: Cascading fallbacks

This method relies on the cascading nature of CSS. This is better to use if you cannot introduce modernizr, but will deliver less-than-perfect UI on non-flexbox browsers. When I first started using flexbox in production, I would use it only on components for internal projects that would look decent without any flexbox styling (i.e. – elements with a matched height). This method is done by specifying display: table (or inline-block, or something else) first, and specifying display: flex below. Cascading will make display: flex override display: table for browsers that recognize it. For browsers that don’t, display: flex will simply be ignored. Here’s a good example of this on CodePen.


 

Now, I am obligated to tell you that using flexbox in production is really ugly due to an insane amount of browser prefixes. The flexbox specification has changed significantly since it was introduced, so you must use browser prefixes in order to ensure maximum support. Here’s my above code snippet, this time with accurate prefixing (max-width used for a Firefox bug):

ul {
     width: 100%;
     display: -webkit-box;     /* OLD - iOS 6-, Safari 3.1-6 */
     display: -moz-box;        /* OLD - Firefox 19- */
     display: -ms-flexbox;     /* IE10 */
     display: -webkit-flex;    /* NEW - Safari and Chrome */
     display: flex;
     -webkit-flex-wrap: wrap;
     -moz-flex-wrap: wrap;
     -ms-flex-wrap: wrap;
     flex-wrap: wrap;
     -webkit-align-content: space-between;
     -moz-align-content: space-between;
     -ms-align-content: space-between;
     align-content: space-between;
     li {
          max-width: 100%;
          -webkit-flex-basis: 100%;
          -moz-flex-basis: 100%;
          -ms-flex-basis: 100%;
          flex-basis: 100%;
          @media only screen and (min-width: @screen-xs-min) {
               max-width: 48%;
               -webkit-flex-basis: 48%;
               -moz-flex-basis: 48%;
               -ms-flex-basis: 48%;
               flex-basis: 48%;
          }
          @media only screen and (min-width: @screen-sm-min) {
               max-width: 32%;
               -webkit-flex-basis: 32%;
               -moz-flex-basis: 32%;
               -ms-flex-basis: 32%;
               flex-basis: 32%;
          }
     }
}

Yikes. CSS preprocessors and autoprefixers will make this less painful, but it’s still lots of code. The decision to use flexbox definitely depends on your project requirements and team preference, as it may seem like overkill to style the same element twice and/or double your lines of code just to support older versions of IE. Unfortunately, this problem will not go away for quite a while, since IE8 is somehow still around.

 

Flexbox is a gold nugget that is gathering dust due to our omnipresent problem of browser support. If every user was on the latest version of Chrome, flexbox would be a no-brainer. Personally, I’m going to use flexbox wherever it is applicable; it’s too powerful to let IE drag it into the void and force it to be forgotten.

Emily Lord

I am a UI developer with over 2 years of experience under my belt. I love learning about modern trends and new ways to make beautiful and responsive web pages. My mission is to put a smile on the faces of both the designers and the Sitecore developers while keeping my code clean and efficient. Learn more about Emily.

Add a Comment

Your email address will not be published. Required fields are marked *

Or request call back