Welcome! Flexbox is one of those CSS features that feels like a superpower the moment it clicks. It’s made for laying out items in a row or column, spacing them out, wrapping them when needed, and aligning them without doing weird “float-left-and-pray” rituals.
CSS Flexbox in one minute
CSS Flexbox is a layout mode that applies to a flex container and its flex items.
- A flex container is an element with
display: flex(orinline-flex). - Its direct children become flex items.
- Flex items can grow, shrink, wrap, and align along two axes.
The big idea: you control layout using two axes:
- Main axis: the direction items flow (row or column).
- Cross axis: perpendicular to the main axis.
.flex {
display: flex;
}
.flex {
display: flex;
gap: 12px;
}
.flex {
display: flex;
gap: 12px;
justify-content: space-between;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
padding: 12px;
background: #f2f2f2;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 700;
}
OneTwoThree
Your first flex container
When you set display: flex on a container, its direct children line up along the main axis.
display: flexmakes the container a block-level element (it behaves like a block on the outside).display: inline-flexmakes the container an inline-level element (it behaves like text on the outside).
.flex {
display: flex;
}
.flex {
display: inline-flex;
}
.flex {
display: flex;
width: 320px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.note {
padding: 10px 12px;
background: #fff7d6;
border: 2px solid #111;
margin-bottom: 10px;
}
.flex {
border: 3px solid #111;
padding: 10px;
background: #f2f2f2;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 8px 12px;
font-weight: 700;
}
.inline-demo {
border: 2px dashed #111;
padding: 8px;
}
This dashed box is just to show how the container behaves "on the outside".BeforeAfterABC
Learn more about inline-flex in the CSS Display Inline-Flex Interactive Tutorial.
Flex direction and the axes
flex-direction sets the main axis direction:
row(default): items go left to right (in LTR languages).row-reverse: items go right to left.column: items stack top to bottom.column-reverse: items stack bottom to top.
When you switch direction, your alignment properties don’t change names, but they do change which axis they affect. That’s the main reason Flexbox feels confusing at first.
.flex {
display: flex;
flex-direction: row;
}
.flex {
display: flex;
flex-direction: column;
}
.flex {
display: flex;
flex-direction: row-reverse;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
padding: 12px;
background: #f2f2f2;
height: 280px;
gap: 10px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
}
1234
Wrapping: flex-wrap and flex-flow
By default, flex items try to fit on one line. If they can’t, they’ll shrink to make it work. If you want them to move onto new lines, use flex-wrap: wrap.
flex-wrap: nowrap(default): single line, items shrink if needed.flex-wrap: wrap: items can wrap onto multiple lines.flex-wrap: wrap-reverse: wraps, but flips the cross-axis stacking order.
flex-flow is shorthand for flex-direction + flex-wrap.
.flex {
display: flex;
flex-wrap: nowrap;
}
.flex {
display: flex;
flex-wrap: wrap;
}
.flex {
display: flex;
flex-wrap: wrap-reverse;
}
.flex {
display: flex;
flex-flow: row wrap;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
width: 360px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
width: 140px;
}
Item 1Item 2Item 3Item 4Item 5
justify-content: main-axis alignment
justify-content aligns items along the main axis. When you’re in flex-direction: row, that means horizontal alignment. In flex-direction: column, it becomes vertical alignment.
Common values:
flex-start(orstartin newer specs)centerflex-end(orend)space-betweenspace-aroundspace-evenly
.flex {
display: flex;
justify-content: flex-start;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
}
AlphaBetaGamma
align-items: cross-axis alignment
align-items aligns items along the cross axis. In a row, the cross axis is vertical. In a column, it’s horizontal.
stretch(default): items stretch to fill the cross-axis size (when possible).flex-startcenterflex-endbaseline: aligns text baselines.
.flex {
display: flex;
align-items: stretch;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
height: 160px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
}
.item.tall {
padding: 22px 14px;
font-size: 22px;
}
ShortTallerShort
align-content: when you have multiple lines
align-content controls how rows (or columns) are spaced along the cross axis when there are multiple lines.
Important: it only has an effect when:
- you have wrapping (
flex-wrap: wrap), and - there’s extra cross-axis space (usually because the container has a fixed height).
.flex {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
.flex {
display: flex;
flex-wrap: wrap;
align-content: center;
}
.flex {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
width: 360px;
height: 260px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
width: 100px;
}
12345678
gap: flexbox spacing without margins
gap adds space between flex items. It’s usually nicer than margins because:
- it only creates space between items (no awkward “first/last” margin issues),
- it works cleanly with wrapping,
- it reads like intent: “I want space between items”.
.flex {
display: flex;
gap: 12px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
flex-wrap: wrap;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
width: 120px;
}
Card 1Card 2Card 3Card 4Card 5
flex-grow, flex-shrink, flex-basis up close
Let’s make the “math story” visible. We’ll keep the layout fixed-width, and change only one item’s flex values.
flex-basisis your starting point (often a length like200px).flex-growdecides who gets extra room.flex-shrinkdecides who sacrifices room when there isn’t enough.
.item.focus {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 130px;
}
.item.focus {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 130px;
}
.item.focus {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 230px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
display: flex;
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
width: 550px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 12px 14px;
font-weight: 800;
flex: 0 1 160px;
}
.item.focus {
background: #e8f1ff;
}
AFocusC
The flex shorthand: grow, shrink, basis
The flex property is applied to flex items. It’s shorthand for:
flex-grow: can this item take extra space?flex-shrink: can this item give up space when needed?flex-basis: the item’s “starting size” before growing/shrinking.
Common patterns you’ll see:
flex: 0 0 auto(similar to “don’t grow, don’t shrink, size to content”)flex: 1(meaning1 1 0%in modern flexbox behavior)flex: 1 1 200px(flexible, but prefers 200px)
.item.one {
flex: 0 1 auto;
}
.item.one {
flex: 1 1 0%;
}
.item.one {
flex: 1 1 220px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
display: flex;
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
width: 520px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 12px 14px;
font-weight: 800;
flex: 0 1 140px;
}
.item.one {
background: #e8f1ff;
}
Item 1Item 2Item 3
CSS Flex order: reordering items
order changes the visual order of items without changing the HTML order.
Beginner tip: use this sparingly. Screen readers and keyboard navigation follow the DOM order, not the visual order. So if you move important content around visually, your page can become confusing to navigate.
.item.middle {
order: 0;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
display: flex;
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 12px 14px;
font-weight: 800;
}
.item.middle {
background: #ffe7ef;
}
FirstMiddleLast
align-self: per-item cross-axis control
align-items sets alignment for all items. align-self lets one item break the rules (politely).
- Works on the cross axis.
- Common values:
auto,stretch,flex-start,center,flex-end,baseline.
.item.special {
align-self: auto;
}
.item.special {
align-self: center;
}
.item.special {
align-self: flex-end;
}
.item.special {
align-self: stretch;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.flex {
display: flex;
align-items: flex-start;
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
gap: 10px;
height: 180px;
}
.item {
border: 2px solid #111;
background: #fff;
padding: 12px 14px;
font-weight: 800;
}
.item.special {
background: #e8f1ff;
}
OneSpecialThree
Common CSS flexbox layout patterns
Quick centering
To center items horizontally and vertically inside a container, the classic combo is:
justify-content: centeralign-items: center
.center {
display: flex;
justify-content: center;
align-items: center;
}
.center {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
.center {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 10px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.center {
border: 3px solid #111;
background: #f2f2f2;
height: 220px;
padding: 12px;
}
.badge {
border: 2px solid #111;
background: #fff;
padding: 10px 14px;
font-weight: 800;
}
HelloFlexbox
A simple navbar
A very common pattern is a logo on the left and links on the right. Flexbox makes it effortless: use justify-content: space-between.
Switch to the HTML view to see the structure.
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.links {
display: flex;
gap: 10px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.nav {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px 14px;
}
.brand {
font-weight: 900;
padding: 8px 10px;
border: 2px solid #111;
background: #fff;
}
.links a {
display: inline-block;
padding: 8px 10px;
border: 2px solid #111;
background: #fff;
text-decoration: none;
color: #111;
font-weight: 800;
}
Equal-height cards
Flex items in the same row can stretch to the same height automatically (that’s often align-items: stretch doing its job). Then inside each card, you can use display: flex again to push buttons to the bottom.
margin-top: auto is commonly used to push elements to the bottom of a flex container.
.grid {
display: flex;
gap: 12px;
}
.grid {
display: flex;
gap: 12px;
}
.card {
display: flex;
flex-direction: column;
}
.grid {
display: flex;
gap: 12px;
}
.card {
display: flex;
flex-direction: column;
}
.card .actions {
margin-top: auto;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-sans-serif, system-ui, sans-serif;
padding: 16px;
}
.grid {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
align-items: stretch;
}
.card {
border: 2px solid #111;
background: #fff;
padding: 12px;
width: 180px;
gap: 10px;
}
.card h4 {
margin: 0;
font-size: 18px;
}
.card p {
margin: 0;
font-weight: 600;
}
.btn {
display: inline-block;
padding: 8px 10px;
border: 2px solid #111;
background: #fff7d6;
text-decoration: none;
color: #111;
font-weight: 800;
}
Flexbox debugging checklist
- Nothing happens? Make sure you set
display: flexon the container (not the items). - Items won’t wrap? Add
flex-wrap: wrapand make sure items have a width or basis that can overflow. - align-content does nothing? You need wrapping and extra cross-axis space.
- Why are my items shrinking so much? Flex items default to shrinking. Consider
flex-shrink: 0on a specific item (but use it carefully). - Text overflows weirdly? A common fix is setting
min-width: 0on a flex item that contains long text, so it’s allowed to shrink. - Spacing looks off? Prefer
gapover margins for consistent spacing. - Order changes confuse navigation? Remember: visual order and DOM order can differ. Use
ordercarefully.
CSS Flexbox Conclusion
If you feel comfortable with containers (flex-direction, wrap, justify-content, align-items) and items (flex, align-self, order), you’re already in a great place.
When you are ready for more, check out the CSS Grid Interactive Tutorial.
