CSS Reference Guide

All TopicsPlayground

Flexbox

The Flexible Box Layout module provides an efficient way to lay out, align, and distribute space among items in a container — even when their size is unknown or dynamic.

LayoutAlignmentOne-DimensionalEssential

Display Flex

Setting display: flex on a container makes it a flex container, and its direct children become flex items. This is the foundation of all flexbox layouts.

CSS
.container {
  display: flex;         /* block-level flex container */
}

.container-inline {
  display: inline-flex;  /* inline-level flex container */
}
Live Example — display: flex vs block

Without flex (normal block flow):

Item 1
Item 2
Item 3

With display: flex:

Item 1
Item 2
Item 3
Key Concept: Axes

Flexbox works along two axes: the main axis (defined by flex-direction) and the cross axis (perpendicular to it). By default, the main axis runs left-to-right and the cross axis runs top-to-bottom.

Flex Direction

The flex-direction property defines the main axis direction — the direction flex items are placed in the container.

CSS
.container {
  display: flex;
  flex-direction: row;             /* default — left to right */
  flex-direction: row-reverse;     /* right to left */
  flex-direction: column;          /* top to bottom */
  flex-direction: column-reverse;  /* bottom to top */
}
Live Example — All flex-direction Values

flex-direction: row (default)

1
2
3

flex-direction: row-reverse

1
2
3

flex-direction: column

1
2
3

flex-direction: column-reverse

1
2
3

Flex Wrap

By default, flex items try to fit onto one line. flex-wrap controls whether items are forced onto a single line or can wrap onto multiple lines.

CSS
.container {
  display: flex;
  flex-wrap: nowrap;        /* default — single line, items may shrink */
  flex-wrap: wrap;          /* items wrap to new lines */
  flex-wrap: wrap-reverse;  /* items wrap in reverse order */
}

/* Shorthand: flex-flow combines direction + wrap */
.container {
  flex-flow: row wrap;
}
Live Example — flex-wrap: wrap
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7

Resize the browser to see items wrap to new lines.

Justify Content

Distributes space along the main axis. This is the most commonly used alignment property in flexbox.

CSS
.container {
  display: flex;
  justify-content: flex-start;      /* default — pack items to start */
  justify-content: flex-end;        /* pack items to end */
  justify-content: center;          /* center items */
  justify-content: space-between;   /* equal space between items */
  justify-content: space-around;    /* equal space around items */
  justify-content: space-evenly;    /* truly equal spacing */
}
Live Example — All justify-content Values

justify-content: flex-start

A
B
C

justify-content: flex-end

A
B
C

justify-content: center

A
B
C

justify-content: space-between

A
B
C

justify-content: space-around

A
B
C

justify-content: space-evenly

A
B
C
space-between vs space-around vs space-evenly

space-between: First item at start, last at end, equal space between. space-around: Equal space around each item (edges get half-size space). space-evenly: Truly equal space everywhere, including edges.

Align Items

Aligns items along the cross axis (perpendicular to flex-direction). Works on a single line of items.

CSS
.container {
  display: flex;
  align-items: stretch;     /* default — fill the container height */
  align-items: flex-start;  /* align to top */
  align-items: flex-end;    /* align to bottom */
  align-items: center;      /* center vertically */
  align-items: baseline;    /* align text baselines */
}
Live Example — All align-items Values

align-items: stretch (default)

Short
Medium
text
Tall

align-items: flex-start

Short
Medium
text
Tall

align-items: flex-end

Short
Medium
text
Tall

align-items: center

Short
Medium
text
Tall

align-items: baseline

Small text
Big text
Normal

Align Content

Aligns multiple lines of flex items along the cross axis. Only works when flex-wrap: wrap is set and there are multiple lines.

CSS
.container {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;     /* lines packed to top */
  align-content: flex-end;       /* lines packed to bottom */
  align-content: center;         /* lines centered */
  align-content: space-between;  /* equal space between lines */
  align-content: space-around;   /* equal space around lines */
  align-content: stretch;        /* default — lines stretch */
}
Live Example — align-content: center
1
2
3
4
5
6
align-items vs align-content

align-items aligns items within a single flex line. align-content aligns the lines themselves when there is extra space on the cross axis. align-content has no effect on single-line flex containers.

Gap

The gap property sets spacing between flex items without adding margins. Clean, simple, and predictable.

CSS
.container {
  display: flex;
  gap: 1rem;                 /* both row and column gap */
  row-gap: 1rem;             /* gap between rows */
  column-gap: 0.5rem;        /* gap between columns */
  gap: 1rem 0.5rem;           /* row-gap column-gap */
}
Live Example — gap: 1rem
Item 1
Item 2
Item 3
Item 4
Gap vs Margins

Unlike margins, gap only creates space between items, never on the outer edges. This eliminates the need for negative margin hacks on the container.

Flex Grow

flex-grow defines how much a flex item should grow relative to other items when there is extra space on the main axis. Default is 0 (do not grow).

CSS
.item {
  flex-grow: 0;   /* default — don't grow */
  flex-grow: 1;   /* take up available space */
  flex-grow: 2;   /* grow twice as much as flex-grow:1 */
}
Live Example — flex-grow Ratio Demo

All items start with equal base size, but grow at different rates:

All flex-grow: 1 (equal distribution)

grow: 1
grow: 1
grow: 1

Ratio 1 : 2 : 1

grow: 1
grow: 2
grow: 1

Ratio 1 : 3 : 1

grow: 1
grow: 3
grow: 1

Flex Shrink

flex-shrink defines how much a flex item should shrink relative to other items when there is not enough space. Default is 1.

CSS
.item {
  flex-shrink: 1;   /* default — will shrink */
  flex-shrink: 0;   /* won't shrink — maintains size */
  flex-shrink: 2;   /* shrinks twice as fast */
}
Live Example — flex-shrink: 0 prevents shrinking
shrink:0 (150px fixed)
shrink:1 (will shrink)
shrink:1 (will shrink)

Flex Basis

flex-basis sets the initial main size of a flex item before growing or shrinking. Think of it as the "ideal" size.

CSS
.item {
  flex-basis: auto;     /* default — use width/height or content */
  flex-basis: 200px;    /* fixed starting size */
  flex-basis: 30%;      /* percentage of container */
  flex-basis: 0;        /* ignore content size, distribute all space */
}
flex-basis vs width

When both flex-basis (not auto) and width are set, flex-basis wins. Use flex-basis for flex layouts — it's the semantically correct property and works regardless of flex-direction.

Flex Shorthand

The flex shorthand combines flex-grow, flex-shrink, and flex-basis. Always prefer the shorthand — it sets better defaults.

CSS
.item {
  /* flex: grow shrink basis */
  flex: 0 1 auto;          /* default (when not using shorthand) */

  flex: 1;                   /* flex: 1 1 0   — grow equally, ignore content size */
  flex: auto;                /* flex: 1 1 auto — grow equally, respect content */
  flex: none;                /* flex: 0 0 auto — rigid, no grow, no shrink */
  flex: 0 0 200px;           /* fixed 200px, no flexibility */
}
Live Example — Common flex Shorthand Values

flex: 1 (equal sizing, ignores content)

Short
Much longer content here
Mid

flex: auto (equal sizing, respects content)

Short
Much longer content here
Mid

flex: none (rigid, content-sized)

Short
Much longer content here
Mid

flex: 0 0 200px (fixed 200px)

200px fixed
200px fixed
flex:1 vs flex:auto

flex:1 sets flex-basis:0, so items size equally regardless of content. flex:auto sets flex-basis:auto, so items with more content get more space. For equal columns, use flex:1.

Align Self

Overrides align-items for a single flex item. Allows individual items to position themselves differently on the cross axis.

CSS
.item {
  align-self: auto;        /* default — follow align-items */
  align-self: flex-start;  /* top */
  align-self: flex-end;    /* bottom */
  align-self: center;      /* center */
  align-self: stretch;     /* fill */
  align-self: baseline;    /* text baseline */
}
Live Example — align-self Overrides
default
(flex-start)
align-self:
center
align-self:
flex-end
align-self:
stretch

Order

The order property controls the visual order of flex items without changing the HTML source order. Default is 0.

CSS
.item-a { order: 3; }  /* appears last */
.item-b { order: 1; }  /* appears first */
.item-c { order: 2; }  /* appears second */
Live Example — Visual Reordering with order

HTML order: A, B, C, D. Visual order changed via CSS order property:

A (order:3)
B (order:1)
C (order:4)
D (order:2)

Displayed: B, D, A, C

Accessibility Warning

order only changes visual rendering, not tab order or screen reader order. Users navigating with a keyboard or assistive technology will encounter items in their DOM order. Use with caution.

Perfect Centering

The classic CSS centering problem, solved elegantly with flexbox in just 3 lines.

CSS
/* The holy grail of centering */
.center-perfect {
  display: flex;
  justify-content: center;  /* horizontal center */
  align-items: center;      /* vertical center */
}

/* Alternative: place-content shorthand */
.center-alt {
  display: flex;
  place-content: center;   /* centers both axes */
}

/* Another way: margin auto on the child */
.center-container {
  display: flex;
}
.center-container > .child {
  margin: auto;             /* centers in both directions */
}
Live Example — Perfect Centering
Perfectly Centered

Real-World Patterns

Common UI layouts built with flexbox. Copy these patterns for your projects.

Navbar

CSS
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1.5rem;
}
.navbar-links {
  display: flex;
  gap: 1.5rem;
  align-items: center;
}
Live Example — Navbar Layout
Logo
Home About Contact Sign Up

Card Row

CSS
.card-row {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.card {
  flex: 1 1 300px;    /* grow, shrink, min 300px */
}
Live Example — Responsive Card Row
Card One

This card will grow and shrink. Try resizing the browser window.

Card Two

Equal sizing with flex:1, wrapping when items reach their minimum width.

Card Three

Responsive without a single media query.

Media Object

CSS
.media {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}
.media-image {
  flex-shrink: 0;           /* don't shrink the image */
  width: 64px;
  height: 64px;
  border-radius: 50%;
}
.media-body {
  flex: 1;                  /* take remaining space */
}
Live Example — Media Object
Jane Cooper

This is the classic media object pattern. The avatar never shrinks thanks to flex-shrink:0, and the text takes all remaining space with flex:1.

Input Group

CSS
.input-group {
  display: flex;
}
.input-group input {
  flex: 1;                 /* input takes available space */
}
.input-group button {
  flex-shrink: 0;          /* button stays fixed */
}
Live Example — Input Group
Enter your email...
Subscribe

Gotchas

The min-width: 0 Problem

Flex items have min-width: auto by default, which means they won't shrink smaller than their content. This causes overflow with long text or code. Fix: add min-width: 0 or overflow: hidden to the flex item.

CSS
/* Problem: text overflows flex container */
.flex-item {
  flex: 1;
  /* Long text or pre elements will overflow! */
}

/* Solution */
.flex-item {
  flex: 1;
  min-width: 0;   /* allow shrinking below content size */
}
The margin: auto Trick

In flexbox, margin: auto absorbs extra space. A common trick: margin-left: auto on the last nav item pushes it to the right. This is more powerful than it seems — it works on both axes.

CSS
/* Push the last item to the right */
.nav-item:last-child {
  margin-left: auto;   /* absorbs all extra space */
}
Live Example — margin-left: auto Push
Home About Blog Login

Login button pushed to the right with margin-left: auto

Column Direction Pitfall

When using flex-direction: column, the main axis becomes vertical. This means justify-content works vertically and align-items works horizontally. The container also needs a defined height for justify-content to have visible effect.

Pro Tips

Sticky Footer with Flexbox

Wrap your page in a flex container with flex-direction: column and min-height: 100vh. Set flex: 1 on the main content area — the footer automatically sticks to the bottom.

CSS
/* Sticky footer pattern */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
main {
  flex: 1;   /* pushes footer down */
}
Equal Height Cards

Flex items in a row automatically get equal heights (because of align-items: stretch). To make the card content push the button to the bottom, make the card itself a flex column with flex-direction: column, and use margin-top: auto on the button.

CSS
.card-row {
  display: flex;
  gap: 1rem;
}
.card {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.card-button {
  margin-top: auto;  /* pushes to bottom of card */
}
Flex vs Grid: When to Choose

Use Flexbox for one-dimensional layouts (a single row or column) and for content-driven sizing. Use Grid for two-dimensional layouts (rows AND columns) and for layout-driven sizing. They work beautifully together — use grid for the page layout and flex for components inside it.

Debug with Outline

When debugging flex layouts, add outline: 1px solid red to flex items (not border — outlines don't affect layout). Or use browser DevTools which now have excellent flexbox overlays.

PreviousDisplay & Positioning