Woodridge Tech Talk

Our ongoing series of bi-weekly technical presentations

Flexbox (flexible box layout)

CSS3 layout for modern browsers

More and more often I’ve been hearing, reading and sneaking peaks at code that is utilizing flexbox. What! Have we finally reached the tipping point!? Are we really finally ready to start using flexbox for our client projects? I first starting reading about flexbox years ago, but because of a lack of browser support, I quickly put it out of my mind as a viable layout tool. Perhaps it may be time to give it a little more attention. This week’s technical discussion focuses on just what flexbox offers, how it works and whether or not it’s time to start implementing this extremely promising tool. So I rolled up my sleeves, did some internet digging to unearth an answer to my first question: Just what is flexbox anyway!?

The CSS3 Flexible Box, or flexbox, is a layout mode providing for the arrangement of elements on a page such that the elements behave predictably when the page layout must accommodate different screen sizes and different display devices. Mozilla Developer Network

What is flexbox?

  • The promise is, that flexbox was designed as a better way to handle layout, alignment, and spacing of layout elements in an html container – even when (or perhaps – especially when) the content is dynamic. Sounds promising.
  • Additionally, flexbox is meant to ensure that elements behave predictably in different window sizes and devices.
  • Flexbox is supposed to be easily defined in CSS and HTML (including media queries)
  • Flexbox is designed to be “directionally agnostic” vs the more common block (vertical) and inline (horizontal) layout structures
  • A couple of authors suggested that it is best used for smaller modules rather than a more complex web application (turns out I’m not so sure I agree with this one.)

How do I start using flexbox?

It didn’t take long to realize that if we were going to use flexbox, we would need to be a bit more accommodating than traditional CSS. Well, this is nothing too new with CSS3 as we’ve been leveraging browser prefixes for quite some time, but what is unusual about flexbox it that it has evolved over time and we as CSS authors/developers, need to write both ‘Old’ and ‘New’ syntax.

According to Chris Coyier back in 2013, we can combine the two syntaxes to achieve pretty good browser support. If it turns out to be as powerful and useful as the promise – this would be a small price to pay I think. Added bonus – we can quickly assess just how out of date information on the web is, simply by reviewing the syntax that is being used. Bad news – there is also something that authors call a “tween” state that was created as a bridge from old and new. I’m going to focus on the new syntax.

Here’s an example of the different flexbox syntaxes:

  • NEW: display: flex;
  • TWEEN: display; -ms-flexbox;
  • OLD: display: box;

Core Concepts

It seems the backbone concept of flexbox is that it consists of Flex Containers and Flex Items

Flex Container

Declared on a parent element using the display property. display: flex or display inline-flex

Flex Items

No real surprise, flex items are positioned inside of a flex container along with something called a “flex line”.

flexbox-1

Flex Line

The concept of a flex line is that by default all flex items line up in a row on a single axis. Flex line is not something that is declared or explicitly stated in the code, but the concept can be modified with some specific css properties such as flex-direction and flex-wrap. A rope analogy is also used to explain this concept: Imagine a rope that is anchored to opposite sides of a container with items attached to it.

  • All flex items line up on a flex line
  • By default, one flex-line per flex container
  • Flex lines can be ‘strung’ vertically or horizontally (default).
  • The flex line concept purports to force us to abandon our previous layout thinking of top-to-bottom, left-to-right or rows/columns. Hmmm.

flexbox-lines

Flex Direction

Changing the orientation and direction of the items on a line is easy using the flex-direction property. flex-direction accepts four values:

  • row (default value), lines all items up on a line from left to right
  • row-reverse actually reverses the order of the items on the page rather than just sliding everything over like right aligning would do. What?!
  • column, changes the orientation of the flex line from horizontal to vertical, so everything lines up from the top down.
  • column-reverse maintains the vertical line, but reverses the order similar to row-reverse
Flex Wrap

While the default behavior is that all flex items link us on a single line, entirely unlike what an actual stretched line or rope would do, flex lines can be extended to multiple lines using a property called flex-wrap. Using a property called justify-content on the flex container, you can easily align your elements left, right or center.

For this one, let’s actually look at a little code to see how things are coming together. Here’s some sample markup of an outer flex-container with multiple flex items inside of it.

<div class="flex-wrapper">
     <div>A</div>
     <div>B</div>
     <div>C</div>
     <div>D</div>
     <div>E</div>
     <div>F</div>
     <div>G</div>
     <div>H</div>
     <div>I</div>
     <div>J</div>
     <div>K</div>
     <div>L</div>
</div>

The corresponding css to start flexing our muscles…doh!  Thanks to The Ultimate Flexbox Cheat Sheet for helping with the backward compatibility and notation.  Sidenote: Formatting styles have been removed.

#flex-wrapper {
    /* flexbox setup */
    display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
    display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
    display: -ms-flexbox; /* TWEENER - IE 10 */
    display: -webkit-flex; /* NEW - Chrome */
    display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}

 #flex-wrapper>div {
    /* flex items */
    flex: 1;  /* each flex item will have the same size */
 }

flex items line up on a row

Ok – here we see a screenshot of all the flex items lining up nicely along a horizontal flex line from left to right. Problem is, there’s not a lot of space for content – so let’s add a bit of flex-wrap and let’s set a min-width on our flex-items just so that we can see what’s going on.

#flex-wrapper {
    /* flexbox setup */
    display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
    display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
    display: -ms-flexbox; /* TWEENER - IE 10 */
    display: -webkit-flex; /* NEW - Chrome */
    display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */

    -webkit-flex-wrap: wrap;
    flex-wrap: wrap;
}

 #flex-wrapper>div {
    /* flex items */
    flex: 1;  /* each flex item will have the same size */
    min-width: 50px;
 }

Now, this is interesting. As you can see, because we added the flex-wrap and min-width properties, our flex line is now wrapping to a new line. What is perhaps unexpected is that all the items on the second line are stretched to take up the additional space that is available. Is anyone getting any ideas?

flex-wrap

Big & Simple

Order

What I didn’t cover yet in regards to the flex line concept, is a really big change in the way that I’d previously thought about laying out content. Items on a flex-line can be reordered right in the css layer! This is potentially a huge idea and one that could allow semantic markup to become even more achievable. By simply placing a css property called order on a flex-item, you can reposition it on your flex line. The value that is placed on order is simply an integer. Using my previous example, I want to try to take the second flex-item ‘B’ and place it at the end of the flex line. Using one very simple line of css proved to be all I needed! (background color added for drama)

#flex-wrapper>:nth-child(2) {
    order: 12;
}

flex order

Nested Flex Lines

Flex items are the direct children of a flex-container, so inheritance does not apply very deeply. The good news is that you can create as many flex containers as you need to and they can all behave independently of one another. Imagine a site layout where you have a left and right rail with a large center area for your main content. You can layout your main areas with a flex-container and then place another flex-container in your main content to handle a series of elements – like a list of products, or images or both. This nested flex line can have a different orientation, order or any other flexbox attribute. Good to know.

Flex Grow and Flex Shrink

Flex-items can easily be assigned values that allow them to grow or shrink relative to the other items on the line. Unitless values serve as the proportion. e.g. an item that has been given the property of flex-grow: 2 will be twice as big as the other items on the line. Flex-shrink behaves the same way: flex-shrink: 2 (no negative values).

Flex Basis

According to Chris Coyier, flex-basis “defines the default size of an element before remaining space is distributed”. Hmmm, I’ll need to think on that one. Length (2em, 200px, etc) or keyword values (which is pretty much limited to ‘auto’ as I understand it) are accepted and they seem to have a rather different impact on items. Check out this graphic to make sense of things. If flex-basis is set to 0, the extra space around it is not factored in. If set to auto (keyword), the extra space is distributed by its flex-grow value, any other value, I assume, works that into the equation. I suggest messing around with some code to understand the relationship between flex-basis, flex-grow and flex-shrink – which leads to the next core concept: the flex shortcut.

Shortcut

There is an important short cut for flex-items – called simply flex. flex is a combination of flex-grow and flex-shrink(optional) and flex-basis(optional). Default = 0 1 auto

RECOMMENDED over using individual properties.

.item {
 flex: 1 0 0;
}

 

Centering Things (Vertical Centering) using flexbox

Perhaps the most out-of-the (flex) box functionality that will be used by almost everyone immediately is the illusive vertical-centering! CSS developers have been searching for over a decade for a clean, semantically accurate, non-nested, flexible (I could go on) way to center an element in a vertical space. Imagine a container that has a fixed height. You have an image that is dynamically added and can have a variety of orientations and dimensions. You want to center that image in the container both horizontally and vertically regardless of its size. Seems easy – but as you probably know, it can be a major headache!

Enter flexbox.

It really couldn’t be easier, and it works on both horizontal and vertical flex lines. Simply add the justify-content property to your flex-container and give it a value of ‘center‘ – BAM – you’re done. Adding align-items: center; takes care of the horizontal centering. This is huge people!

 

#flex-wrapper.horiz {
    flex-direction: row;
    -webkit-justify-content: center;
    justify-content: center;
}

#flex-wrapper.vert {
    -webkit-align-items: center;
    align-items: center;
}

<div id="flex-wrapper" class='horiz'>
    <div>A</div>
</div>

<div id="flex-wrapper" class='vert'>
    <div>B</div>
</div>

<div id="flex-wrapper" class='horiz vert'>
    <div>C</div>
</div>

 

flexbox-centering

Conclusion … Is it time to start using flexbox?

While I feel I’ve only scratched the surface and I haven’t dug deep into browser support and what can and can’t be accomplished, I’ve now read enough from developers who I respect who seem to be working flexbox into their daily workflow. Like any project check out sites like canisuse.com and consider your audience. On one hand, Microsoft support is (not surprisingly) poor, but to their credit, they were early adopters of some of the concepts. Controlled environments and responsive apps using technologies like Cordova seem to be excellent candidates to get started, and from what I can tell flexbox is not going away and will continue to be adopted more and more. I plan on finally getting on board – that I can say with certainty!

 

View the original slide deck on Slideshare.net: Slideshow Presentation

Categories: Tech Talk, UX Design