This cheatsheet is a lookup table for the CSS Flexbox properties: what each one does, its initial value, and the exact values the flex shorthand expands to. It is for developers who know the idea of Flexbox and need the right property name or the right number. The one confusion it clears up is that flex: 1 is not flex: 1 1 auto, because it sets the basis to 0%.
These go on the element with display: flex.
| Property | Values | Initial | Does |
|---|---|---|---|
| `display` | `flex`, `inline-flex` | n/a | Makes direct children flex items |
| `flex-direction` | `row`, `row-reverse`, `column`, `column-reverse` | `row` | Sets the main axis |
| `flex-wrap` | `nowrap`, `wrap`, `wrap-reverse` | `nowrap` | Allows items to move to a new line |
| `flex-flow` | direction and wrap in any order | `row nowrap` | Shorthand for the two above |
| `justify-content` | `flex-start`, `flex-end`, `center`, `space-between`, `space-around`, `space-evenly` | `normal` | Places items on the main axis |
| `align-items` | `flex-start`, `flex-end`, `center`, `baseline`, `stretch` | `normal` | Places items on the cross axis, per line |
| `align-content` | `flex-start`, `flex-end`, `center`, `space-between`, `space-around`, `stretch` | `normal` | Spaces the lines of a wrapped container |
| `gap` | one or two lengths | `normal` | Sets row and column gutters |
| `row-gap`, `column-gap` | length or percentage | `normal` | Sets one gutter |
The Flexbox spec lists flex-start and stretch as the initial values of justify-content and align-items. Chromium 153 reports a new flex container as normal for both, and normal behaves like stretch for items. space-evenly and gap come from the CSS Box Alignment module, not from the Flexbox module.
These go on the children.
| Property | Values | Initial | Does |
|---|---|---|---|
| `flex-grow` | number, 0 or more | `0` | Share of free space the item takes |
| `flex-shrink` | number, 0 or more | `1` | Share of overflow the item gives up |
| `flex-basis` | `auto`, `content`, length, percentage | `auto` | Starting size on the main axis |
| `flex` | `none`, or grow, shrink and basis | `0 1 auto` | Shorthand for the three above |
| `align-self` | `auto`, `flex-start`, `flex-end`, `center`, `baseline`, `stretch` | `auto` | Overrides `align-items` for one item |
| `order` | integer | `0` | Visual position, lowest first |
| `margin: auto` | any side | n/a | Absorbs free space on that side |
Computed grow, shrink and basis, read from Chromium 153:
| You write | Grow | Shrink | Basis |
|---|---|---|---|
| `flex: initial` | 0 | 1 | `auto` |
| `flex: auto` | 1 | 1 | `auto` |
| `flex: none` | 0 | 0 | `auto` |
| `flex: 1` | 1 | 1 | `0%` |
| `flex: 0` | 0 | 1 | `0%` |
| `flex: 2 3` | 2 | 3 | `0%` |
| `flex: 1 200px` | 1 | 1 | `200px` |
| `flex: 0 0 100px` | 0 | 0 | `100px` |
A single unitless number sets grow and then fills in 1 0%. A single length sets only the basis. When the basis is omitted from the shorthand it becomes 0%, which is why flex: 1 items end up equal regardless of their content width.
| `flex-direction` | Main axis | Cross axis | `justify-content` moves items |
|---|---|---|---|
| `row` | horizontal | vertical | left and right |
| `row-reverse` | horizontal, reversed | vertical | start edge is on the right in left-to-right text |
| `column` | vertical | horizontal | up and down |
| `column-reverse` | vertical, reversed | horizontal | start edge is at the bottom |
.box { display: flex; justify-content: center; align-items: center; }
Measured in Chromium 153 for one 60px item in a 400px by 50px container with a 20px-high item, the item sat at x 170 and y 15 from the container top. Use it for a single centered child.
.nav { display: flex; justify-content: space-between; }
.nav-even { display: flex; justify-content: space-evenly; }
Three 60px items in a 400px container, measured x positions:
space-between 0, 170, 340
space-evenly 55, 170, 285
space-between puts the first and last items on the edges. space-evenly leaves equal gaps everywhere, including the edges.
.cols { display: flex; }
.cols > div { flex: 1; }
Three items in a 400px container measured 133.33, 133.34 and 133.33 pixels wide. Use flex: 1 when you want equal columns whatever the content.
.row > .x { flex: 1; }
.row > .y { flex: 2; }
.row > .fixed { width: 100px; }
In a 400px container the widths measured 100, 200 and 100. The fixed item takes its 100px first, and the remaining 300px is shared 1 to 2.
.tags { display: flex; flex-wrap: wrap; gap: 10px; width: 200px; }
.tags > div { width: 80px; }
Five 80px items measured x positions 0, 90, 0, 90, 0, which means two per line with a 10px gutter. Prefer gap over margins, since it adds no space at the container edges.
.bar { display: flex; }
.bar > :first-child { margin-right: auto; }
Three 60px items in a 400px container measured x positions 0, 280 and 340. The auto margin takes all free space, so the first item stays left and the other two sit right.
.a { order: 3; }
.b { order: 1; }
.c { order: 2; }
The measured x positions were 120 for .a, 0 for .b and 60 for .c. Only the painting order changes, not the order in the DOM.
.row { width: 300px; display: flex; }
.logo { width: 200px; flex-shrink: 0; }
.rest { width: 200px; }
Two 200px items in a 300px row measured 150px each by default. With flex-shrink: 0 on the first, the widths measured 200 and 100.
0% and the second keeps the content size, so unequal content gives unequal columns with flex: auto. Use flex: 1 for equal widths.flex-wrap: wrap first, or use align-items.order only for visual changes. Keyboard focus and screen readers still follow the DOM, so the two can disagree.:last-child hacks. Use gap, which is supported on flex containers by the Box Alignment module.normal for justify-content, align-items and align-content on a new flex container, not the flex-start or stretch named in the Flexbox spec.width with flex-shrink: 1 is only a starting size. Items can still end up narrower than the width you wrote, as the 150px result above shows.align-self, flex, order and margins belong on the item.