An Introduction to the CSS Flexbox Module

An Introduction to the CSS Flexbox Module

Tutorial Details
  • Topic: CSS Flexbox
  • Difficulty: Beginner
  • Estimated Completion Time: 30m

CSS, despite its relatively low perceived skill ceiling, always seems to have a killer feature up its sleeve. Remember how media queries made responsive layouts possible and revolutionized front-end development? Well, today, we’re going to talk about a new layout mode, called flexbox – new in CSS3. I’m sure you’re raring to go! Let’s get started after the jump.


CSS Flexbox Support

Currently, the CSS Flexbox specification is a working draft and things will change! The examples this tutorial covers could potentially fail to work in the future, as browsers change their flexbox implementation to match up with the specification. The aim of this tutorial is to provide you with a basic understanding of CSS flexbox, and demonstrate how to use it in your web pages.

Please note that this tutorial will use webkit/non-vendor-prefixed examples for the sake of brevity. Have a look at caniuse.com for a list of browsers that support the flexbox module, and reference the necessary prefixes in your projects, accordingly.


Background on Layout Modes

CSS Flexbox is essentially a layout mode. There are existing layout modes within CSS, and they’ve been there for a long while. One example of a layout mode is block (e.g. display: block). Block layouts are a great way to style entire documents, many elements are treated by the browser as block level, by default; these include common elements, such as paragraphs and divs.

Occasionally, when an element is not block, it’s likely to be inline. Inline level elements include the anchor tag, input tag & the strong tag. The developer tools in Chrome actually allow you to view the “computed style” of an element, which is a great way to determine what CSS properties and values have been applied to elements that weren’t explicitly set by the developer.

Here’s a quick tip for accessing the computed style of an element using JavaScript’s window.getComputedStyle method.

var elem = document.querySelector('h1#someId');
window.getComputedStyle(elem).display; //block

Block and inline layout modes aside, CSS also has tabled and positioned layout modes. The reason layout modes are being referenced is because flexbox is a new layout mode, which allows for greater flexibility when laying out web pages.

The flexbox layout provides us with simple techniques to easily dictate the manner in which items are to be laid out.


How Can You Use Flexbox?

To force an element to use the flexbox layout, we add the flexbox value to the display property.

#container {
	display: flexbox;
}

By default, a flexbox is a block level element; we can define an inline-level element like so:

#container {
	display: inline-flexbox;
}

Similar to the example above, you’ll want to apply the flexbox layout to the parent of the children whose positioning you’d like to control. Let’s look at simple, live example.

<ul>
  <li>An item</li>
  <li>Another item</li>
  <li>The last item</li>
</ul>
ul {
	/* Old Syntax */
	display: -webkit-box;

	/* New Syntax */
	display: -webkit-flexbox;      
}

You’ll notice that the list item elements are now flowing horizontally, similar to how they might render, if we had used float: left. The list item elements can now be referred to as flexbox items.

Note: a direct descendent of a flexbox, which is absolutely positioned, e.g. using position: absolute, cannot be a flexbox item, as it breaks the usual flow.

Very basic example

You may notice that the items (the list item elements) have assumed a horizontal flow (the direction of the flow is also known as the main axis). Fortunately, we are able to control this flow (and thus what is considered to be the main axis) and avoid the use of floats!


Exploring flex-direction

We can apply the flex-direction property and specify the direction in which we wish for our flexbox items to be laid out. The property accepts row, row-reverse, column & column-reverse as values. The default value is row.

Using similar markup to the above example, we can add one more CSS property:value pair: (flex-direction: column)

ul {
	-webkit-flex-direction: column;
}
Very basic example

If working along, go ahead and try changing the column value on the flex-direction property to column-reverse, and witness how the flexbox items are displayed in a columned layout, but in the reverse order.


Wrapping With flex-wrap

By default, a flexbox is single-line. One which cannot contain its children may overflow using the flex-wrap property; we can instruct the flexbox to become multi-line, in which case the flexbox items can wrap over. flex-wrap accepts the values, nowrap (the default value), wrap & wrap-reverse.

Very basic example

Notice how, in the demo, the items ‘wrap’ over, since they cannot be contained within their small 100px parent. Using the developer tools, try toggling the overflow: hidden and -webkit-flex-wrap bits. Without the flex-wrap and overflow properties, the items overflow their parent.

There’s a useful shorthand property for flex-direction and flex-wrap, as shown below:

flex-direction: row;
flex-wrap: nowrap;

//Using the two values above with the flex-flow shorthand we get:
flew-flow: row nowrap;

//flex-direction: column; flex-wrap: wrap;
flex-flow: column wrap; 

A Quickie Example

While certainly not the nicest looking there is, this example menu demonstrates some uses for flexbox.

  • A width of 300px has been set on the flexbox, itself, to demonstrate wrapping.
  • A general idea for a menu could be to utilize media queries in order to serve a mobile friendly menu, where flex-direction: column might make sense.
Boring menu

What would be nice is to instruct the flexbox items to spread out and use the space they have available to them – something like this. That’s what the flex property is for.

Boring menu

Flexing

Flexing is the ability of the container to alter its width or height to fill the available space.”

The flex property is a nice feature; it offers something new that would have been difficult to achieve in the past.

With this property, we can set a preferred size for our items. Do keep in mind that the flex property is applied on flexbox items, not on the flexbox itself. The browser will attempt to set the size of the flexbox items on a per line basis. It will then try to evenly distribute the remaining free space on the items. If we look at the menu example, and use the developer tools to discover the computed width of the flexbox items, we’ll see that it is 78px. Let’s investigate further…

The rcomputed width of a flexbox item

You’re probably wondering, “How did the flexbox items gain their extra space when we set their preferred width to 60px?”

The rcomputed width of a flexbox item
  • In the first line, there are three items, which should be around 60pxflex property (that’s a total of 180px).
  • The width of the entire flexbox is 300px. That, minus 180px (the total preferred size of the items), is 120px. However, it doesn’t appear that we actually have 120px of free space.
  • Each flexbox item has a margin-right of 10px; that’s a total of 30px for three items, leaving us with 90px of free space.
  • But wait, each item also has padding: 5px – that’s 5px of padding on the top, right, bottom, and left. So, similar to the margin-right property, each item uses up 10px of padding in regard to its width. We’re left with 60px of free space – well almost.
  • Each item has border: 1px solid black1px on the left and right sides. A total of two pixels per item, so, for three items, that comes to 6px. We’re now left with 54px of free space.
  • With 54px of free space, we can distribute that equally to the three items on the first line – that’s 18px, per item, which now makes sense why, when we set a preference of 60px, the computed width turned into 78px.

As you may have guessed, the last line (containing the item ‘Contact us’) flexes to the full width of the flexbox.

Flexbox items can be given different widths; an item with a flex of 2 is said to be twice as flexible as an item with a flex of 1. So, when it comes to distributing free space between the two items, the item with a flex of 1 will be given half the space that the item with a flex of 2 receives.


Ordering

Flexbox gives us an easy way to order certain items using CSS, regardless of the order that they appear in the document. Here is a quick example.

Given the following markup:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
ul {
	display: -webkit-flexbox;
}

ul li:nth-child(1) {
	-webkit-flex-order: 2;
}

We can target the first list item element using the nth-child pseudo class, and then apply the flex-order property to it. Flexbox items are, by default, at order 0. By placing the first list item at order 2, the browser will display items 2 & 3 first, which will be followed by item 1.


Alignment

We’re able to align flexbox items on the main axis using the flex-pack property. This property accepts the following as values:

  • start
  • end
  • center
  • justify
  • distribute

The demo for this tutorial provides some examples of the different types of alignment. Looking at the jsbin example, we can see that the items have only been centered on one axis: the main axis. This is essentially the axis upon which the flexbox items are placed.

We can change the axis by adjusting the flex-direction property. By setting it to column, it becomes apparent that the main axis has changed. In order to affect the alignment of the cross axis, (the axis perpendicular to the main axis) we can use flex-align.

Centering an Item

<div class="flexbox">
	<p>I should be centered</p>
</div>
.flexbox {
	display: -webkit-flexbox;    
	-webkit-flex-pack: center;
	-webkit-flex-align: center;
	width: 50%;
	height: 100px;
	background: orange;
}

.flexbox p {
	border: 1px solid green;
	padding: 5px;
}

Definitely check out the live demo if you’re confused.

Centered example

Further Reading

Thanks for reading, and be sure to refer to caniuse.com for a list of browsers that support the flexbox module, as well as which vendor prefixes should be referenced.

Tags: css3
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://wouterj.nl Wouter J

    -webkit-flexbox is now -webkit-flex.

    • https://umaar.com Umar Hansa

      Thanks!

  • Akshay

    They say flex isn’t cool right now! http://html5please.com/#flex

    • https://umaar.com Umar Hansa

      The spec kept changing which isn’t great. I think html5please is right, it’s best to avoid using flexbox until the spec has settled down and browser implementations have caught up. Nonetheless, flexbox is kinda fun to use and it’s interesting to see what will be coming in the near-future!

  • Hamid

    it’s amazing, wonderfull, it’s a very quick article and good looking on flexbox from Umar Hansa, i recommending that for eveyone.

    btw Umar sadly it seems browser still has some issues with it is there any idea from you to what we have to do flexbox while browser are still working on it?

    • https://umaar.com Umar Hansa

      Thank you. If you want to use Flexbox now, Flexie might be an option: http://flexiejs.com/

  • http://nanecie.pl Sebastian S

    It’s great article and CSS Module:)

  • http://nathanrjones.com Nathan Jones

    Great tut!

    I’ve been following CSS3′s flexbox model for a while and your demo on GitHub is one of the cleanest beginner walkthroughs I’ve seen.

  • http://www.williamwalker.me William

    I have to admit that this is the first time I’ve really looked into flexbox and your post done a great job of demonstrating how to use it. Can’t wait for it to have wider browser support along with CSS3 columns.

    • https://umaar.com Umar Hansa

      Thanks, hopefully that day will come soon!

  • grattacazzo

    cool, but too bad there is no IE9 support… there is some kind of shim for that?

    • LeeDi

      I tried using Chrome Frame. It may not be the best solution, but it does work.
      You can always ask your users to install Chrome Frame the first time they’re visiting your site (see: http://www.chromium.org/developers/how-tos/chrome-frame-getting-started)

      Hope this helps!

      • thecodingdude

        Having to make a user install something is counter-intuitive to what HTML5 and the web is supposed to be. Less dependencies and more browser is better.

    • https://umaar.com Umar Hansa

      You might find some useful links in the “Further reading” section above. Flexie claims to offer support for IE 6-9

      Github: https://github.com/doctyper/flexie
      Homepage: http://flexiejs.com/

  • http://namanyayg.com/ Namanyay Goel

    How would be degrade this gracefully? This is a pretty great idea, but, it isn’t even supported by the latest version of firefox, let alone IE, so it could cause some issues..

    • http://wouterj.nl Wouter J

      FireFox has support, with a prefix. But this tutorial is already a little old, because -webkit-flexbox needs to be -webkit-flex.
      As you can see on CanIUse there is full support in Chrome21 and support in Chrome5+, IE10+, FF3.0+ and Safari5.1+. Opera is the only browser that hasn’t any support.

      For IE9- and Opera you can use flexie, a polyfill for the flexbox model.

    • https://umaar.com Umar Hansa

      Ideally, a page which uses flexbox would still look and function similarly with flexbox disabled, however if this isn’t possible Flexie might be able to provide better cross browser support: http://flexiejs.com/

      Firefox should support Flexbox: http://www.caniuse.com/flexbox however the latest version of specification is probably unsupported right now. Mozilla also have some documentation on Flexbox – https://hacks.mozilla.org/2010/04/the-css-3-flexible-box-model/

  • http://satyabhamasahoo.com satya

    Seems to be great article……..

  • http://www.xcellence-it.com Xcellence IT

    Great tutorial to a something which is going to be very useful in feature….

    Thanks

  • http://www.jungmut.com Marcel

    Thanks for this great article and the many insightful examples!

  • Ruturaj

    I am working on my final year project from six months, i have used -webkit-box and all other properties widely. So does my css will work in future? Please suggest me necessary changes i should make.

  • Jon

    Unfortunately, this tutorial is already somewhat outdated. The property names used for ordering and alignment have recently been changed, in an attempt to make them generic rather than flexbox-specific.

  • http://freepsdsource.com saha

    Nice tutorial about css flexbox. CSS flexbox seems to be very useful and helpful.
    Thanks.

  • http://carlmichaelhugh.es carl-michael

    this is awesome. This (these) property potentially solves so many layout issues. It’s like a new toy. I can’t wait to try it!

  • http://www.tutosytips.com johanso

    Thanks, I learn a lot on this site

  • AntoxaGray

    Flex is revolutionary feature and will change how we write our HTML and CSS in the future.

    It will allow to quickly change layout of page with 1 line of code.

    Also I always wanted automatic stretching of elemets, depending on how much elements we have. That was only possible with tables before.

  • http://coder-design.com/ coderdesign

    What browsers support the CSS Flexbox?

  • http://allsnoringcures.com Sisir

    Please publish a Video tutorial on PSD to Responsive HTML5/CSS3 Conversion (please not a on premium tut) :-/

  • md. Rustom Ali khoka

    শিকার জন্য এটা কুব ভালো সাইট হতে পারে ।

  • http://www.wordpressguru.com.au Wordpress Developer

    Was excited … thought it was CSS feature … but seems to be CSS3 …
    Any way its a good read thanks for the article

  • Alex

    Great article ! Is there any browser that supports flex-flow (as well as flex-direction, flex-wrap) right now? Even with Chrome 24 (dev from 3.10.12) I can’t make it work :( –> is there an (old) equivalent ? Thanks for your help

    • Alex

      Ok, got it to work with the canary version. Sorry ;) Anyway thanks for this great article.