Flexbox Revisited: The New Syntax For Flexible Boxes

Last summer I wrote about the css flexible box model. At the time I mentioned how the spec was changing and offered syntax for both the old and “new” specs. Those “new” specs didn’t last long. A newer spec has taken it’s place and I wanted to run through flex layout model again to have more accurate information here.

The bad news is browser support isn’t consistent. The latest versions of all major browsers support the flexible box model in some way, but that support is mixed between the old method and the newest method. I don’t think any browser supported that short lived “new” method.

The current syntax I’ll be using in this post works only in Chrome at the moment and requires the -webkit vendor prefix even though I won’t be showing it here. I created a simple demo or rather me experimenting with a few properties. It’s nothing special, but you can get a feeling for the code involved. Remember though, it’s Chrome only at the moment.

Diagram of a 3 column layout and a single column layout with the same elements
Courtesy of Mozilla Contributors

What Are the Benefits of Flexible Boxes?

If support is still on the patchy side, then why should we care about flexible boxes?

That word flexible should be a big clue. Unlike other types of boxes we can display, this one flexes. It changes as our layout changes, as the browser changes. Flexible boxes allow for automatic resizing of elements within a parent element that’s been resized. Has the word responsive come to mind yet?

Flexible boxes help solve the problem of wanting a different source order when moving from the layout of phone sizes to the layout of widescreen displays. That alone would make them worthwhile in my opinion.

Along the way they make vertical centering elements easier and they even give us a solution for equal height columns. They’ll generally make our lives easier and anyone who’s aware of them is probably jumping at the bit for browsers to support them to the point where we can use them in production.

illustration of directions and sizing terms for a flexbox container
An illustration of the various directions and sizing terms as applied to a ‘row’ flex container.

Flex Layout Box Model

Flex layout, joins the 4 previously introduced layout modes, block (documents), inline (text), table (tabular data), positioned (explicitly positioned elements). Flex is intended for the layout of complex applications and webpages.

To understand how this all works take a look at the image above of 2 flex items inside a row flex container. There are 4 ideas we should take away from the image

  • Axis — Two axis run through a flexbox, a main (primary) axis and a cross (perpendicular to primary) axis. Flex items are laid out along the main axis.
  • Dimension — There is a corresponding main and cross dimension along each axis.
  • Start and end — There are start and end points along each axis. By default flex items flow from start to end and flex lines connect start and end.
  • Size and size property — Flex items will have main and cross sizes from their width and height properties. Which is which depends on which axis is main and which is cross. The property that aligns with the main axis is the main size and the property that aligns with the cross axis is the cross size.

.

Flex items inside a flex container
Courtesy of Mozilla Contributors

Flex Containers and Flex Items

You create a flex container by setting the display property on an element.

1
2
.flex-1 { display: flex; }
.flex-2 { display: inline-flex; }

The above generates a block level and inline level flexbox respectively. Since this is a different layout model, flex containers aren’t exactly like block and inline boxes.

  • column-* properties of multicolumn have no effect on a flex container
  • float and clear have no effect on flex items (with small exceptions)
  • vertical-align has no effect on flex items

Flex containers hold 0 or more flex items that can also contain other elements. If a flex item is empty, holding only whitespace, it’s treated as though display: none were set on it.

3 flexboxes shown in a different order than the default
3 flexbox items with their order set to display flexbox 3, flexbox 1, and flexbox 2 respectively

Ordering and Orientation

We have 4 properties to help us order and orient flex items.The first 3 are applied to the flex container and the last will get applied to the flex items.

flex-direction — sets the direction of the main axis. There are 4 possible values

  • row
  • row-reverse
  • column
  • column-reverse

Rows set the main axis parallel to the inline axis and column sets it parallel to the block axis. By default the direction will be from start to end unless -reverse is used.

flex-wrap — determines whether the flex container is a single or multiple line container. Here we have 3 values

  • nowrap
  • wrap
  • wrap-reverse

Using nowrap sets the container as a single line container, while either of the wrap values sets it as multiline. The wrap value means lines flow from cross start to cross end, while the reverse is true with wrap-reverse as you probably guessed. When nowrap is set the flex items will remain on a single line even if that means overflowing the flex container.

flex-flow — this 3rd property is actually a shorthand for the 2 above set in the following order: <flex-direction> | <flex-wrap>

order — is set on the flex items and it takes an integer value. As you’d expect, it sets the order in which the flex items display. This single property solves the html source order problem.

An illustration of the values of justify-content
The five ‘justify-content’ keywords and their effects on a flex container with three colored items.

Flexibility

There are 3 properties to determine how a a growing or shrinking flex container distributes free space to its flex items. These are set on the flex items.

  • flex-grow — how much a flex item will grow relative to other flex items
  • flex-shrink — how much a flex item will shrink relative to other flex items
  • flex-basis — the initial main size of the flex item, before free space is distributed
  • flex shorthand — none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

flex-grow and flex-shrink take a number as a value, while flex-basis takes the width of a box or auto.

The above properties work relative to one another. For example if you have 3 flex items with flex-grow and flex-shrink values of 1, 1, and 2 respectively, the last item will grow/shrink twice as much as the other two which will grow/shrink the same amount as the container expands and contracts.

fAn illustration of the values of align-items
The five ‘align-items’ keywords and their effects on a flex container with four colored items.

Alignment

Finally we have a few properties to align flex items and flex lines inside the flex container. To align flex items along the main axis you use the justify-content property (on the flex container), which comes with the following values

  • flex-start — packed toward start
  • flex-end — packed toward end
  • center — packed toward center
  • space-between — evenly distributed in line
  • space-around — evenly distributed in line with half size spaces at ends

In the cross axis direction you use align-items and align-self.

  • align-items — set on the container it becomes the default for all flex items
  • align-self — set on the items it overrides align-items for that specific flex item

Both properties can have any of 5 different values. The first 3, flex-start, flex-end, and flex-center are similar to the above. The 2 different values are:

  • baseline — which aligns the baseline of flex items to the cross line
  • stretch — which stretches things a little to align flex items and baseline

The align-self property can also have a value of auto, which means use the default align-items value.

Flex lines can be aligned within the flex container when there is extra space in the cross direction. The align-content property is used to do this with values similar to justify content. The one difference is the additional stretch value which stretches the lines from start to end.

Summary

Hopefully this new syntax will become the standard and hopefully browsers will adjust to adopt the new syntax sooner rather than later. The flexible box model offers us a lot of new options and helps solve quite a few problems we’re having when it comes to responsive design.

If you’ve played around with flex boxes before the new syntax shouldn’t be too hard to work with. In many ways it maps to the old syntax.

Once again I created a demo you can check out to see the code in action and how it ties together. Working with flexbox isn’t as complicated as I might have made it seem in this post, though I’d be lying if I said I could get everything to work as I expected.

Have you played around with the news syntax? One of the older syntaxes? Just looking forward to the day we can use this in practice?

Download a free sample from my book, Design Fundamentals.

4 comments

Leave a Reply

Your email address will not be published.

css.php