Flexbox

Demo starter files. The starter files for this demo are already finished. This demo also includes multiple flexbox examples in one file, so a live version isn't very illustrative.

Flex is a relatively new display property (in addition to display: block, inline, table, etc) that is specifically designed for layout. The goal is to partially remove the need for "hacky" older CSS techniques using floats, inline-block, or CSS tables that are stretched to solve layout problems they were never originally intended to.

There are two types of elements when using flexbox - a parent flex container, and child flex items. When an element is set to display: flex, it becomes a flex container, and all of its direct children become flex items. Flex items must be direct children of the parent.

All of the flexbox properties and short definitions are below, but it's much easier to learn the properties by seeing them in action, so we'll skip straight to the demo files.

Properties Available on the Parent (flex container)

Properties on the parent define the direction of content flow on the container (either vertically or horizontally), and how the flex items should be spaced and distributed in the container. Here are all of the available properties:

display: flex
flex-flow
  • Shorthand for flex-direction flex-wrap
flex-direction: row (default) | column
  • This defines the main axis that flex items will be plotted along.
  • row means inline according to the writing direction. In English and other Latin-based languages that means horizontally left to right.
  • column means the block direction, which in English is vertical top to bottom.
flex-wrap: nowrap (default) | wrap | wrap-reverse
  • Defines whether flex items are allowed to wrap to new lines when there is not enough space.
  • Reverse wrap is also allowed (e.g. if flex-direction: row, new lines wrap upward), creating interesting possibilities.
justify-content: flex-start (default) | flex-end | center | space-between | space-around
  • Alignment of items along the main axis (horizontally, if flex-direction: row)
  • If the flex items don't fill all available space in the flex container, this property controls how flex items should be distributed.
align-items: flex-start | flex-end | center | baseline | stretch (default)
  • Alignment of items along the cross axis. (vertically, if flex-direction: row)
  • Flex items can vary in height. This property controls how the shorter flex items are aligned.
align-content: flex-start | flex-end | center | space-between | space-around | stretch (default)
  • Controls distribution of flex items within the container, only when there are multiple rows.

Properties available on the Children (flex items):

Properties on the flex items are mainly for defining their size and stretchiness. Here are all of the available properties:

flex
  • Shorthand for flex-grow flex-shrink flex-basis
  • Default is flex: 0 1 auto
  • Note from the spec: "It is recommended that you use this shorthand property rather than set the individual properties. The short hand sets the other values intelligently."
  • Basic values of flex (including keywords): https://www.w3.org/TR/css-flexbox-1/#flex-common
  • When an element is a flex item, the flex setting is used instead of the normal width or height setting to determine the size of the box along the main axis. If the parent is not a flex container (display: flex), this property has no effect. https://www.w3.org/TR/css-flexbox-1/#flex-property
  • Margins and padding on flex items should not be set using percentages because of inconsistent browser behavior. https://www.w3.org/TR/css-flexbox-1/#item-margins
  • When flex-basis is the only value supplied to this property, and is a number, it must have units even if the value is 0, otherwise it'll be interpreted as a flex-grow value!
flex-grow: 0 (default) | <number>
  • Defines how much the flex item will grow relative to its counterparts.
  • Accepts an integer with no units, which becomes a proportion.
  • 0 means no growth above the flex-basis value
  • For example: An item that has flex-grow: 2 when all other flex items have flex-grow: 1, will expand at twice the rate of the others to fill the available space.
flex-shrink: 1 (default) | <number>
  • Defines how much the flex item will shrink when the space on the main axis has been filled.
  • Accepts an integer with no units, which becomes a proportion.
  • 0 means no shrink below the flex-basis value
  • A higher flex-shrink value means that item will shrink faster than its sibling flex items.
flex-basis: auto (default) | <length> | content | 0 | none
  • Desired size of the flex item along the main axis. The flex item "wants" to be this width or height, but may not be depending on flex-grow and shrink values.
  • This setting supersedes the regular CSS width or height setting of a flex item (whichever is along the main axis)
  • 0 or "none" here equates to "absolute" flex, meaning the ratios of grow and shrink take the flex item's literal width, not its width based on its content (refer to the spec for a helpful diagram) https://www.w3.org/TR/css-flexbox-1/#flex-property
  • The "content" keyword = flex-basis auto and main dimension width/height auto. Was not in original spec and therefore flex-basis: auto + width or height: auto should be a fallback for the same behavior.
align-self: auto (default) | flex-start | flex-end | center | baseline | stretch
  • Align an individual flex item along the cross axis. Overrides the align-items value on the parent flex container.
order
  • Changes the display order of flex items (only on the visual CSS layer).
  • This does not affect source HTML order, screen reader order, or tab order, so be careful using this on forms inputs!
  • The order property on all flex items is initially 0 for all the flex items. When all items are 0 their natural order (from the HTML) is used. Setting one item to 1 would therefore put it at the end. -1 ensures an item ends up at the start. Obviously a more advanced order can also be specified on multiple flex items, e.g. 1 4 3 2 5 6.

Miscellaneous Notes

Auto margins can be used on any side of a flex item for alignment. This is helpful to know but keep in mind that properties on the flex container are also used to control alignment and distribution of flex items.

Percentage margins are currently still disputed (feb 2016), and not supported in the same way across all supporting browsers.

Loose content nested directly inside a flex containers is wrapped in anonymous flex items, except white space, which behaves as display none. In other words, all direct children of flex-containers become flex items regardless of whether you've given them any flex related properties.

Tables inside flex items work mostly as expected, except for some minor changes to things like flex items that are also serving as table containers.

Absolute and fixed positioning of flex items is possible, but their coordinates are always relative to the flex container, and have some other minor behavior changes.

Overflow rules on flex items work as expected.

What About Grid?

Flexbox and CSS Grid share many of the same core concepts. As a rule of thumb, Flexbox is for laying out content in one direction, and Grid is for layout in two dimensions. This is often confusing for beginners since flexbox has the ability to span multiple rows, which seems like two dimensions.

To put it another way, you can draw lines through a flexbox layout in one direction (usually horizontal). If you need to be able to draw straight lines through your layout in both directions, you need grid.