The flexbox is a new layout mode. It is great when the page layout must accommodate different screen sizes and different display devices.
Child elements in a flexbox can be laid out in any direction and can have flexible dimensions to adapt to the display space. Positioning child elements is thus much easier, and complex layouts can be achieved more simply and with cleaner code, as the display order of the elements is independent of their order in the source code. This independence intentionally affects only the visual rendering, leaving speech order and navigation based on the source order.
The defining aspect of the flex layout is the ability to alter its items' width and/or height to best fill the available space on any display device. A flex container expands items to fill available free space, or shrinks them to prevent overflow.
The flexbox layout algorithm is direction-agnostic as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased. While the block layout works well for pages, it lacks sufficient definition to support application components that have to change orientation, resize, stretch, or shrink as the user agent changes, flips from vertical to horizontal, and so forth.
The flex layout is based on flex-flow directions
. You can take a look at this image from the W3C specs
The items will be laid out following either the main axis (from main-start to main-end) or the cross axis (from cross-start to cross-end).
main axis
The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the flex-direction property (see below).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.
There are several new properties introduced by flexbox. Some of them affect the parent element and some of them its children.
Parent flexbox properties
Children flexbox properties
It enables flexbox in the element.
/* possible values */
.flex {
display: flex;
}
.flex {
display: inline-flex;
}
Demo: http://codepen.io/asainz/pen/zGPKOv
Gist: https://gist.github.com/asainz/79f3771b97ec05828686
This establishes the main-axis. This means, which direction the children items will follow (horizontal or vertical).
.flex{
flex-direction: row; /* default */
}
.flex{
flex-direction: row-reverse;
}
.flex{
flex-direction: column;
}
.flex{
flex-direction: column-reverse;
}
Demo: http://codepen.io/asainz/pen/BNmLQG
Gist: https://gist.github.com/asainz/6be47ef9f134978275a9
Flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property.
.flex{
flex-wrap: nowrap; /* default */
}
.flex{
flex-wrap: wrap;
}
.flex{
flex-wrap: wrap-reverse;
}
Demo: http://codepen.io/asainz/pen/doZpWZ
Gist: https://gist.github.com/asainz/bbb5e721f37e84c19965
Shorthand for flex-direction
and flex-wrap
.
.flex{
flex-flow: row nowrap;
}
.flex{
flex-flow: ANY_DIRECTION_OPTION ANY_WRAP_OPTION;
}
This defines the alignment along the main axis (flex-direction value). It helps distribute extra free space.
.flex{
justify-content: flex-start; /* default */
}
.flex{
justify-content: flex-end;
}
.flex{
justify-content: center;
}
.flex{
justify-content: space-between;
}
.flex{
justify-content: space-around;
}
Demo: http://codepen.io/asainz/pen/VLrKEd
Gist: https://gist.github.com/asainz/52cdb17f79092d924fe8
This defines the default behaviour for how flex items are laid out along the cross axis on the current line. Think of it as the justify-content version for the cross-axis (perpendicular to the main-axis or flex-direction value)
.flex{
align-items: flex-start; /* default */
}
.flex{
align-items: flex-end;
}
.flex{
align-items: center;
}
.flex{
align-items: baseline;
}
.flex{
align-items: stretch;
}
Demo: http://codepen.io/asainz/pen/bdYwZb Gist: https://gist.github.com/asainz/23c61da77ac38332d32c
This aligns a flex container's lines within when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.
This property has no effect when there is only one line of flex items.
.flex{
align-content: flex-start;
}
.flex{
align-content: flex-end;
}
.flex{
align-content: center;
}
.flex{
align-content: space-between;
}
.flex{
align-content: space-around;
}
.flex{
align-content: stretch; /* default */
}
Demo: http://codepen.io/asainz/pen/zGPoYP
Gist: https://gist.github.com/asainz/0e52b9953df313b4e28d
It changes the order the elemnts are rendered. By default, they are rendered in the order defined in the DOM
.item{
order: NUMBER;
}
Demo: http://codepen.io/asainz/pen/VLrmzN
Gist: https://gist.github.com/asainz/75e6ec316b83f45e4884
This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
If all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others. Negatives number are invalid.
.item{
flew-grow: NUMBER; /* defult to 1 */
}
Demo: http://codepen.io/asainz/pen/VLrmzN
Gist: https://gist.github.com/asainz/75e6ec316b83f45e4884
This defines the default size of an element before the remaining space is distributed. The main-size value makes it match the width or height, depending on which is relevant based on the flex-direction.
.item {
flex-basis: LENGTH | auto; /* default auto */
}
For instance
.flex.first-example p:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 20em;
}
.flex.first-example p:last-child {
flex-grow: 2;
flex-shrink: 2;
flex-basis: 20em;
}
Both flex items want to be 20em wide. Because of the flex-grow, if the flex container is larger than 40em, the 2nd child will take twice as much leftover space as the first child.
If flex-basis
is set to 0, the extra space around content isn't factored in. If set to auto, the extra space is distributed based on it's flex-grow value
Demo: http://codepen.io/asainz/pen/XbzpOW
Gist: https://gist.github.com/asainz/1ab76be1ff4cb9dc0c7e
This defines the ability for a flex item to shrink if necessary. Negatives number are invalid. Think of it as the opposite of flex-grow
. When there is no space to accommodate all the items based on their flex-grow
and flex-basis
values, flex-shrink
indicates how much an item will be reduced. If we have to items, and the first one has flex-shrink: 1
and the last one has flex-shrink: 2
, the lat one will be reduced twice as much as the first one.
.item{
flex-shrink: NUMBER; /* defult to 1 */
}
Demo: http://codepen.io/asainz/pen/RPjKBV
Gist: https://gist.github.com/aac145b936b3a9274236
Shorthand for flex-grow
, flex-shrink
and flex-basis
.flex{
flex-flow: 0 1 auto; /* default */
}
.flex{
flex-flow: NUMBER NUMBER [LENGTH | auto];
}
Allows to override the alignment set by align-items
for an individual item.
.flex{
align-self: flex-start; /* default */
}
.flex{
align-self: flex-end;
}
.flex{
align-self: center;
}
.flex{
align-self: baseline;
}
.flex{
align-self: stretch;
}
Demo: http://codepen.io/asainz/pen/LVOyLX
Gist: https://gist.github.com/07695f9140ca9a15e14e
There's a great online tool that you can use to enforce the understanding of this properties and play with them. Flexbox in 5 minutes!