An Introduction to Flexbox
Meet Flexbox. The CSS3 Flexible Box, or more widely known as Flexbox, is a new and powerful layout mode in CSS3. It provides us with a box model optimized for laying out user interfaces. With Flexbox, vertical centering, same-height columns, reordering and changing direction is a breeze. This is thanks to its layout algorithm being direction-agnostic (as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased).
Flexbox is pretty easy and straightforward to use. However, implementing it on more complex layouts can get a little out of hand so it should only be used for small application components and simpler layouts.
Browser support for Flexbox is pretty good. According to caniuse.com around 93% of people are now running a browser that supports it.
Basics
In the picture above you can see the properties and the terminology that’s used to describe the flex container and flex items.
- main axis – The main axis of a flex container is the primary axis along which flex items are laid out. It’s not necessarily horizontal (depending on the flex-direction property).
- main-start | main-end – The flex items are placed within the container starting from main-start and going to main-end.
- main size – A flex item’s width or height, whichever is in the main dimension, is the item’s main size. The flex item’s main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
- cross axis – The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
- cross-start | cross-end – Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
- cross size – The width or height of a flex item, whichever is in the cross dimension, is the item’s cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.
How to use Flexbox
The HTML is as simple as it gets:
To use Flexbox we need to set the display
property to flex
on parent element (.flex-container).
All immediate child elements (.flex-item) are automatically set to flex items.
Prefixing
To support the most browsers possible, Flexbox requires us to add some vendor prefixing. The problem is that the flexbox spec has changed over time, creating an “old”, “tweener”, and “new” versions. Prepending properties with the vendor prefix (-moz-, -webkit-, -ms-) isn’t enough cause there are actually entirely different property and value names in different flexbox spec versions.
The best way to handle this is to run CSS through Autoprefixer which passes CSS and adds vendor prefixes to CSS rules using values from caniuse.com.
Note: all CSS in the following code snippets is un-prefixed.
Flexbox container properties
Notes about flex container:
* all of the column-* properties have no effect on a flex container.
** the ::first-line and ::first-letter pseudo-elements do not apply to flex containers.
flex-direction
This property is used to specify the direction of the flex container’s main axis, thus defining the direction flex items are placed in the flex container.
Values:
* default value for flex-direction
is row
** row
and row-reverse
are dependent of the writing mode so in rtl context they will be reversed.
flex-wrap
By default the flex container fits all flex items into one line. Using this property we can change that. We can tell the container to lay out its items in single or multiple lines, and the direction the new lines are stacked in.
Values:
* default value for flex-wrap
is nowrap
** these properties are dependent of the writing mode so in rtl context they’ll be reversed.
flex-flow
flex-flow property is a shorthand flex-direction
and flex-wrap
properties.
Values:
* default value for flex-flow
is row nowrap
justify-content
justify-content property aligns flex items along the main axis of the current line of the flex container. It helps distribute left free space when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size.
Values:
* default value for justify-content
is flex-start
align-items
The align-items property defines how flex items are laid out along the cross axis on the current line. You can think of it as the justify-content version for the cross-axis.
Values:
* default value for align-items
is stretch
align-content
The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis (similar to how justify-content aligns individual items within the main-axis).
Values:
* default value for align-content
is stretch
Flexbox item properties
Notes about flex items:
* float, clear and vertical-align have no effect on a flex item, and do not take it out-of-flow.
order
By default, flex items are laid out in the order they are added inside the container. Using the order
property we can control the order in which they appear in the flex container.
Values:
* default value for order
is 0
flex-grow
This property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items.
Values:
* default value for flex-grow
is 0
** negative numbers are invalid
flex-shrink
The flex-shrink specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items.
Values:
* default value for flex-shrink
is 1
flex-basis
This property takes the same values as the width and height properties, and specifies the initial main size of the flex item.
Values:
* default value for flex-basis
is auto
flex
This property is the shorthand for the flex-grow, flex-shrink and flex-basis properties. Among other values it also can be set to auto (1 1 auto) and none (0 0 auto).
* default value for flex
is 0 1 auto
** W3C encourages to use the flex shorthand rather than the separate component properties, as the shorthand correctly resets any unspecified components to accommodate common uses.
align-self
This align-self property allows the default alignment (or the one specified by align-items) to be overridden for individual flex items. Refer to align-items explanation for flex container to understand the available values.
Values:
Conclusion
There you go! All Flexbox properties in one place!
I encourage you to go and try to build a few simple page layouts with it. You’ll be pleasantly surprised at the flexibility (no pun intended) it provides.
If you don’t feel like making something from scratch, you can experiment with all Flexbox properties using this great tool built by Dimitar Stojanov.
Resources and inspiration: