📐

CSS Flexbox

Complete CSS Flexbox reference — container properties, item properties and real-world layout patterns

Container Setup

Enable flexbox and control the main axis direction

css·Enable flexbox
.container {
  display: flex;        /* block-level flex container */
}

.container-inline {
  display: inline-flex; /* inline-level flex container */
}
css·flex-direction — main axis
.container {
  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 */
}
css·flex-wrap — overflow behaviour
.container {
  flex-wrap: nowrap;       /* default: all items on one line */
  flex-wrap: wrap;         /* items wrap onto multiple lines */
  flex-wrap: wrap-reverse; /* wraps upward */
}
css·flex-flow — direction + wrap shorthand
.container {
  /* flex-flow: <direction> <wrap> */
  flex-flow: row nowrap;       /* default */
  flex-flow: row wrap;
  flex-flow: column wrap;
  flex-flow: column-reverse wrap-reverse;
}

Main Axis — justify-content

Distribute items along the main axis (horizontal by default)

css·justify-content values
.container {
  justify-content: flex-start;    /* ▐██░░░░░░░░░░░▌ items at start */
  justify-content: flex-end;      /* ▐░░░░░░░░░░░██▌ items at end */
  justify-content: center;        /* ▐░░░░░██░░░░░░▌ items centered */
  justify-content: space-between; /* ▐█░░░░░█░░░░░█▌ equal gaps between */
  justify-content: space-around;  /* ▐░█░░░░█░░░░░█░▌ equal space around */
  justify-content: space-evenly;  /* ▐░░█░░░█░░░█░░▌ equal space everywhere */
}

Cross Axis — align-items & align-content

Align items perpendicular to the main axis

css·align-items — single-line cross axis
.container {
  align-items: stretch;     /* default: items fill cross-axis height */
  align-items: flex-start;  /* items align to cross-axis start */
  align-items: flex-end;    /* items align to cross-axis end */
  align-items: center;      /* items centered on cross axis */
  align-items: baseline;    /* items aligned by text baseline */
}
css·align-content — multi-line cross axis
/* Only applies when flex-wrap: wrap and there are multiple lines */
.container {
  align-content: stretch;       /* default: lines stretch to fill */
  align-content: flex-start;    /* lines packed to start */
  align-content: flex-end;      /* lines packed to end */
  align-content: center;        /* lines centered */
  align-content: space-between; /* equal gaps between lines */
  align-content: space-around;  /* equal space around lines */
  align-content: space-evenly;  /* equal space everywhere */
}
css·gap — spacing between items
.container {
  gap: 16px;           /* equal row and column gap */
  gap: 16px 24px;      /* row-gap column-gap */
  row-gap: 16px;
  column-gap: 24px;
}

Item Properties

Control how individual flex items grow, shrink and size themselves

css·flex-grow — take up available space
/* flex-grow: <number> — proportion of free space to take */
.item { flex-grow: 0; }  /* default: don't grow */
.item { flex-grow: 1; }  /* take all available space */

/* Ratio example: sidebar gets 1 part, main gets 3 parts */
.sidebar { flex-grow: 1; }
.main    { flex-grow: 3; }
css·flex-shrink — give up space when cramped
/* flex-shrink: <number> — how much to shrink relative to siblings */
.item { flex-shrink: 1; }  /* default: shrink proportionally */
.item { flex-shrink: 0; }  /* never shrink — useful for fixed sidebars */
.item { flex-shrink: 3; }  /* shrink 3× faster than siblings */
css·flex-basis — initial size before grow/shrink
.item { flex-basis: auto; }    /* default: use width/height */
.item { flex-basis: 0; }      /* start from nothing, grow from zero */
.item { flex-basis: 200px; }  /* fixed starting size */
.item { flex-basis: 25%; }    /* percentage of container */
.item { flex-basis: content; } /* size based on content */
css·flex shorthand
/* flex: <grow> <shrink> <basis> */
.item { flex: 0 1 auto; }  /* default */
.item { flex: 1; }         /* flex: 1 1 0  — grow, shrink, from zero */
.item { flex: auto; }      /* flex: 1 1 auto */
.item { flex: none; }      /* flex: 0 0 auto — completely rigid */
.item { flex: 1 200px; }   /* grow from 200px base */

/* Common pattern: equal-width columns */
.col { flex: 1; }
css·align-self — override container alignment
.item {
  align-self: auto;       /* default: inherit align-items */
  align-self: flex-start;
  align-self: flex-end;
  align-self: center;
  align-self: stretch;
  align-self: baseline;
}
css·order — reorder without changing HTML
/* order: <integer> — default is 0, lower renders first */
.item-first  { order: -1; } /* moved before all order: 0 items */
.item-last   { order: 1;  } /* moved after all order: 0 items */

/* Visual reorder for mobile without touching markup */
@media (max-width: 768px) {
  .sidebar { order: 2; }
  .main    { order: 1; }
}

Layout Patterns

Real-world flexbox recipes you'll reach for constantly

css·Perfect centering (horizontal + vertical)
/* Method 1: flex on parent */
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Method 2: margin auto on child */
.parent {
  display: flex;
}
.child {
  margin: auto;
}
css·Holy grail layout — header, footer, sidebar, main
/* Full-page layout: sticky footer, flexible main */
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.page header,
.page footer {
  flex-shrink: 0; /* never shrink */
}

.page .body {
  display: flex;
  flex: 1;        /* fill remaining vertical space */
}

.page .sidebar { flex: 0 0 240px; } /* fixed-width sidebar */
.page .main    { flex: 1; }         /* flexible main content */
css·Responsive card grid with wrapping
.grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.card {
  flex: 1 1 280px; /* grow, shrink, min 280px before wrapping */
  max-width: 400px;
}

/* Cards fill row evenly and wrap cleanly at 280px */
css·Navbar — logo left, links right
.navbar {
  display: flex;
  align-items: center;
  padding: 0 24px;
  height: 64px;
}

.navbar .logo {
  margin-right: auto; /* pushes everything else to the right */
}

.navbar nav {
  display: flex;
  gap: 24px;
  align-items: center;
}
css·Sidebar layout with scrollable main
.layout {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.sidebar {
  flex: 0 0 260px;
  overflow-y: auto;
}

.main {
  flex: 1;
  overflow-y: auto; /* main scrolls independently */
}
css·Media object — icon/avatar beside text
.media {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.media__image {
  flex-shrink: 0;   /* image never squishes */
  width: 48px;
  height: 48px;
}

.media__body {
  flex: 1;          /* text fills remaining space */
  min-width: 0;     /* allows text truncation to work */
}
css·Input with button pinned to right
.input-group {
  display: flex;
  gap: 8px;
}

.input-group input {
  flex: 1;          /* input expands to fill space */
  min-width: 0;
}

.input-group button {
  flex-shrink: 0;   /* button stays at its natural width */
}
css·Equal-height columns regardless of content
.columns {
  display: flex;
  gap: 24px;
  align-items: stretch; /* default — columns match tallest sibling */
}

.column {
  flex: 1;
}

/* Each column card fills full column height */
.column .card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.column .card .footer {
  margin-top: auto; /* push footer to bottom of card */
}

Gotchas & Fixes

Tricky flexbox edge cases and how to solve them

css·Text truncation inside flex item
/* Text doesn't truncate inside flex items by default */

/* Fix: set min-width: 0 on the flex item */
.item {
  flex: 1;
  min-width: 0; /* ← critical */
}

.item p {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
css·Image stretching inside flex container
/* Images stretch to fill cross axis by default (align-items: stretch) */

/* Fix 1: align the image itself */
.container img {
  align-self: flex-start; /* or center, flex-end */
}

/* Fix 2: override on container */
.container {
  align-items: flex-start;
}

/* Fix 3: add a wrapper div around the image */
css·Last row of wrapped items stretching
/* With flex: 1 and flex-wrap: wrap, last row items stretch to fill */

/* Fix: add invisible spacer elements */
.grid::after {
  content: "";
  flex: 1 1 280px; /* same flex-basis as real items */
  max-width: 400px;
}

/* Or use CSS Grid for this pattern instead */
css·flex: 1 vs flex: 1 1 0 vs flex: auto
/* These look similar but behave differently */

/* flex: 1  →  flex: 1 1 0%  — starts from zero, distributes all space evenly */
.equal-cols { flex: 1; }

/* flex: auto  →  flex: 1 1 auto  — starts from content size, distributes leftover */
.content-aware { flex: auto; }

/* flex: none  →  flex: 0 0 auto  — completely rigid, ignores free space */
.rigid { flex: none; }

/* Rule of thumb:
   - Equal columns?  → flex: 1
   - Grow but respect content?  → flex: auto
   - Fixed, never change? → flex: none  or  flex: 0 0 <size> */
css·Margin auto — the flex power tool
/* margin: auto consumes all free space in that direction */

/* Push single item to far end */
.nav-items {
  display: flex;
  gap: 16px;
}
.nav-items .logout {
  margin-left: auto; /* pushes logout to right edge */
}

/* Center one item, keep others at start */
.toolbar {
  display: flex;
}
.toolbar .center {
  margin: auto; /* true center regardless of siblings */
}

/* Space between two groups */
.group-a { margin-right: auto; }