CSS Layout

Flexbox

Flexbox is a CSS layout model that makes it easy to align and distribute space among items in a container. Here's how it works and how to use it.

beginner14 min readUpdated Sep 15, 2026
navbar.css
css
/* navbar.css */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.navbar__links {
  display: flex;
  gap: 1.5rem;
}
Introduced in
CSS3 (2012)
Specification
CSS Flexible Box Layout Module Level 1
Display values
flex, inline-flex
Browser support
All modern browsers

Hands-on

Try Flexbox live

Edit the CSS to see how justify-content and align-items affect the layout.

Try Flexbox live

Edit the CSS to see how justify-content and align-items affect the layout.

Why it matters

Why Flexbox matters

Flexible layouts

Flexbox lets you arrange items in rows or columns with dynamic sizing, making complex layouts simple and predictable.

Easy alignment

Vertically and horizontally centering content — one of the hardest CSS tasks before Flexbox — is now a single line of code.

Responsive by nature

Items can grow, shrink and reflow automatically, so layouts adapt to different screen sizes without media queries.

The big picture

The three ideas behind Flexbox

A main axis, a cross axis and flexible sizing. Once you know which axis you are on, every property makes sense.

Main axis

Direction

flex-direction sets the line items flow along, and justify-content distributes them on it.

Cross axis

Align

The perpendicular axis, where align-items and align-content position items.

Flexible sizing

Grow & shrink

flex-grow, flex-shrink and flex-basis let items share the available space.

Flexbox at a glance

The core properties

Two-axis model

Main axis and cross axis control how items are placed and sized.

Direction control

flex-direction switches the main axis between row and column.

Alignment power

justify-content and align-items position items along each axis.

Grow and shrink

Items can expand to fill space or shrink to fit available room.

Ordering

The order property reorders items visually without changing the DOM.

Consistent spacing

The gap property adds even spacing between flex items.

A short history

From floats to flexible layout

  1. 2009

    Flexbox spec drafted

    The W3C publishes the first Working Draft of the Flexible Box Layout Module.

    09
  2. 2012

    Flexbox reaches Candidate Recommendation

    Browser vendors begin implementing the updated syntax with display: flex.

    12
  3. 2015

    Wide browser support

    All major browsers support Flexbox, making it production-ready for most projects.

    15
  4. 2018

    CSS Grid complements Flexbox

    Grid becomes widely supported for 2D layouts while Flexbox remains the go-to for 1D alignment.

    18
  5. Today

    Industry standard

    Flexbox is the default layout tool in CSS frameworks, component libraries and everyday development.

    Today

The complete guide

Flexbox: Everything you need to know

What is Flexbox?

Flexbox is a CSS layout model designed to make it easy to align, distribute and order space among items inside a container. Before Flexbox, developers relied on floats, positioning and table-based layouts to do even simple things like centering a div or creating a navigation bar with equal-width items. Those approaches worked, but they were fragile and verbose. Flexbox replaced most of them with a clean, predictable system.

The key idea is the two-axis model. Every flex container has a main axis and a cross axis. By default the main axis runs horizontally and the cross axis runs vertically, but you can swap them with flex-direction. Everything about Flexbox — alignment, spacing, wrapping — is described in relation to these two axes. Once you understand that mental model, the properties become intuitive.

Flexbox is also one-dimensional. It lays items out in a single row or a single column at a time. If you need to control both rows and columns simultaneously, CSS Grid is the better tool. But for the vast majority of component-level layouts — navigation bars, card rows, form groups, footers — Flexbox is exactly what you need.

Flex container vs flex items

Flexbox works through a parent-child relationship. You turn a parent element into a flex container by setting display: flex. Its direct children automatically become flex items and start following Flexbox rules.

/* style.css */
.container {
  display: flex;
}

.container > * {
  /* These are now flex items */
}

This distinction matters because every Flexbox property applies to either the container or the items — never both. Container properties control the layout environment: axis direction, alignment, wrapping and gap. Item properties control how individual items behave within that environment: how much they grow, shrink, their base size and their order.

A container can also use display: inline-flex to behave like an inline element while still using Flexbox on its children. In practice, display: flex (block-level) covers most use cases.

flex-direction

flex-direction sets the direction of the main axis. It is the most fundamental Flexbox property because every other property depends on which way the main axis runs.

/* style.css */
.container {
  display: flex;
  flex-direction: row; /* default */
}

The four values:

  • row — items flow left to right. This is the default and the most common.
  • row-reverse — items flow right to left.
  • column — items flow top to bottom.
  • column-reverse — items flow bottom to top.
/* style.css */
.row {
  flex-direction: row;
}

.column {
  flex-direction: column;
}

.row-reverse {
  flex-direction: row-reverse;
}

.column-reverse {
  flex-direction: column-reverse;
}

Changing flex-direction swaps which axis is the main axis and which is the cross axis. When flex-direction is row, justify-content controls horizontal distribution and align-items controls vertical alignment. When flex-direction is column, those roles reverse.

justify-content

justify-content aligns flex items along the main axis. It controls how extra space is distributed between or around items.

/* style.css */
.container {
  display: flex;
  justify-content: center;
}

The most common values:

  • flex-start — items pack toward the start of the main axis (default).
  • center — items center along the main axis.
  • flex-end — items pack toward the end of the main axis.
  • space-between — items spread out with equal space between them, no space at the edges.
  • space-around — items have equal space around them, so the gaps between items are twice the edge gaps.
  • space-evenly — items have exactly equal space between them and at the edges.
/* style.css */
.start {
  justify-content: flex-start;
}

.center {
  justify-content: center;
}

.between {
  justify-content: space-between;
}

.around {
  justify-content: space-around;
}

.evenly {
  justify-content: space-evenly;
}

space-between is the most used value for navigation bars — the logo sits on the left, the links on the right, with space in the middle. space-evenly gives a more balanced distribution for things like icon bars or tag lists.

align-items

align-items aligns flex items along the cross axis. While justify-content distributes space along the main axis, align-items controls how items sit within the cross axis.

/* style.css */
.container {
  display: flex;
  align-items: center;
}

The key values:

  • stretch — items stretch to fill the cross axis (default).
  • flex-start — items align to the start of the cross axis.
  • center — items center along the cross axis.
  • flex-end — items align to the end of the cross axis.
  • baseline — items align by their text baseline.
/* style.css */
.container {
  display: flex;
  align-items: stretch; /* default */
}

.centered {
  align-items: center;
}

.bottom {
  align-items: flex-end;
}

.baseline-aligned {
  align-items: baseline;
}

The baseline value is useful when items have different font sizes or padding — it ensures their text lines up along the same invisible line. The stretch default is why flex items often appear taller than you expect: they expand to fill the cross axis by default.

align-content

align-content controls how multiple lines of flex items are spaced along the cross axis. It only has an effect when flex-wrap is set to wrap and the content wraps onto multiple lines.

/* style.css */
.container {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
}

Without flex-wrap: wrap, align-content does nothing because there is only one line. When content does wrap, the values mirror justify-content:

  • flex-start — lines pack toward the start.
  • center — lines center along the cross axis.
  • flex-end — lines pack toward the end.
  • space-between — lines spread out with equal space between.
  • space-around — lines have equal space around them.
  • space-evenly — lines have exactly equal spacing.
  • stretch — lines stretch to fill available space.

For single-line flex containers, align-items is what you need. align-content becomes relevant for multi-line layouts like tag clouds or wrapped button groups.

flex-wrap

By default, flex items try to fit on a single line. flex-wrap lets items wrap onto multiple lines when they run out of room.

/* style.css */
.container {
  display: flex;
  flex-wrap: wrap;
}

The three values:

  • nowrap — all items stay on one line (default). Items may shrink to fit.
  • wrap — items wrap onto new lines as needed.
  • wrap-reverse — items wrap onto new lines, but the cross axis direction is reversed.
/* style.css */
.single-line {
  flex-wrap: nowrap; /* default */
}

.multi-line {
  flex-wrap: wrap;
}

.reversed-wrap {
  flex-wrap: wrap-reverse;
}

Wrapping is essential for responsive layouts. A navigation bar with many links can use flex-wrap: wrap so items move to a new line on smaller screens without overflowing. Combined with gap, wrapped layouts look clean without extra margins.

flex-grow, flex-shrink, flex-basis

These three properties control how flex items share space along the main axis. They work together to determine each item’s final size.

flex-basis sets the initial size of an item before extra space is distributed. It works like width but is respected by the Flexbox algorithm.

/* style.css */
.item {
  flex-basis: 200px;
}

flex-grow controls how much an item expands to fill available space. The default is 0, meaning items do not grow. A value of 1 means the item takes an equal share of leftover space.

/* style.css */
.item-a {
  flex-grow: 1;
}

.item-b {
  flex-grow: 2; /* takes twice as much leftover space as item-a */
}

flex-shrink controls how much an item contracts when there is not enough space. The default is 1, meaning items shrink proportionally. A value of 0 prevents shrinking.

/* style.css */
.item {
  flex-shrink: 0; /* will not shrink, may overflow */
}

The shorthand flex combines all three:

/* style.css */
.item {
  flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
}

.item {
  flex: 0 0 200px; /* no grow, no shrink, fixed 200px */
}

The flex: 1 shorthand is one of the most useful patterns in Flexbox — it gives every item an equal share of available space, which is perfect for equal-width columns, split views and responsive grids.

order property

By default, flex items appear in the order they appear in the HTML. The order property lets you reorder them visually without changing the DOM.

/* style.css */
.item-a {
  order: 2;
}

.item-b {
  order: 1; /* appears first visually */
}

.item-c {
  order: 3; /* appears last visually */
}

All items default to order: 0. Lower numbers come first. Items with the same order value appear in source order. Negative values are valid and will place items before those with the default order.

This is useful for responsive designs where you want a sidebar to appear above the main content on mobile but below it on desktop — change the order with a media query instead of restructuring the HTML.

gap property

The gap property adds consistent spacing between flex items. It replaces the old margin hacks that were once necessary for spacing in flex layouts.

/* style.css */
.container {
  display: flex;
  gap: 1rem;
}

You can set different values for row and column gaps:

/* style.css */
.container {
  display: flex;
  flex-wrap: wrap;
  row-gap: 1rem;
  column-gap: 2rem;
}

Unlike margins, gap only adds space between items — not before the first or after the last item. This makes it predictable and removes the need for negative margins or extra wrapper elements. It works with both single-line and multi-line flex layouts.

Common Flexbox patterns

Once you know the properties, the patterns follow naturally. Here are the most common layouts Flexbox solves.

Centering content:

/* style.css */
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

This is the classic Flexbox flex — it centers a child element both horizontally and vertically inside its parent. Before Flexbox, centering vertically was a notorious problem.

Navigation bars:

/* style.css */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.nav-links {
  display: flex;
  gap: 1.5rem;
}

The logo sits on the left, the links on the right, and everything stays vertically centered. Adding gap to the links keeps them evenly spaced.

Card layouts:

/* style.css */
.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card {
  flex: 1 1 300px;
}

Cards grow to fill available space, shrink when needed, and wrap to new lines on smaller screens. The 300px basis sets a minimum comfortable width.

Holy grail layout:

/* style.css */
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.content {
  display: flex;
  flex: 1;
}

.sidebar {
  flex: 0 0 250px;
}

.main {
  flex: 1;
}

The page is a column that fills the viewport. The middle section is a row with a fixed-width sidebar and a flexible main area. This pattern was extremely difficult before Flexbox.

When to use Flexbox vs Grid

Flexbox and CSS Grid are complementary, not competing. The simplest rule: use Flexbox for one dimension, Grid for two.

Use Flexbox when:

  • You are laying out items in a single row or column.
  • You need to align or distribute space among items.
  • You are building component-level layouts: navbars, button groups, form rows, card rows.
  • You want items to wrap naturally to new lines.
  • You need to center content.

Use Grid when:

  • You need to control both rows and columns simultaneously.
  • You are building page-level layouts with header, sidebar, main and footer.
  • You want explicit placement of items in a grid.
  • You need tracks to size based on the grid container rather than the content.

In practice, most projects use both. A page layout uses Grid for the overall structure, while individual components within that layout use Flexbox for internal alignment. They solve different problems and work beautifully together.

Best practices

  • Use gap instead of margins — it only adds space between items, avoiding edge spacing issues.
  • Use the flex shorthandflex: 1 is cleaner than setting grow, shrink and basis separately.
  • Avoid fixed widths on flex items — let flex-basis and flex-grow handle sizing for responsiveness.
  • Prefer flex-wrap: wrap for responsive layouts instead of media queries for item sizing.
  • Use align-items: center for vertical centering — it is the most reliable approach.
  • Combine with min-width: 0 on flex items that might overflow — flex items do not shrink below their content size by default.
  • Use semantic HTML inside flex containers — Flexbox handles layout, not meaning.
  • Test with different content lengths — Flexbox layouts should adapt to short and long content gracefully.

Common mistakes

  • Setting display: flex on the items instead of the container.
  • Forgetting that align-content requires flex-wrap: wrap to have any effect.
  • Using fixed width on flex items instead of flex-basis.
  • Not setting min-width: 0 on items that might overflow their flex container.
  • Overusing !important to override flex item sizing instead of understanding the flex algorithm.
  • Applying Flexbox properties to the wrong axis — forgetting that flex-direction swaps the main and cross axes.
  • Ignoring accessibility — Flexbox changes visual order with order but not DOM order, so screen readers still follow the source.

Is Flexbox still worth learning in 2026?

Absolutely. Flexbox is not a passing trend — it is the foundational layout system for modern CSS. Every major framework, component library and design system relies on it. CSS Grid complements Flexbox for two-dimensional layouts, but Flexbox remains the default for component-level alignment, spacing and distribution. Understanding Flexbox also makes Grid easier to learn because the axis model and alignment properties carry over directly. If you are building anything for the web, Flexbox is a skill you will use every day.

How to learn Flexbox

Flexbox is visual, so the best way to learn it is to see it in action:

  1. Start with display: flex and justify-content — see how items distribute along one axis.
  2. Add align-items — understand the cross axis and how it relates to flex-direction.
  3. Experiment with flex-direction: column — see how the axes swap.
  4. Try flex-wrap: wrap and gap — build a multi-line layout.
  5. Play with flex-grow, flex-shrink and flex-basis — understand how items share space.
  6. Build real layouts: a navbar, a card row, a centered hero, a sidebar layout.
  7. Use an interactive tool like Flexbox Froggy or CSS Tricks’ Flexbox Guide to visualise every property.

From there, move on to CSS Grid for two-dimensional layouts. Our interactive CSS tutorial covers Flexbox, Grid and responsive design with hands-on exercises.

Spacing flex items

gap adds even space between items and works with wrapping, unlike margins on each child.

Prefer
.row {
  display: flex;
  gap: 1rem;
}
Avoid
.row > * {
  margin-right: 1rem;
}
.row > *:last-child {
  margin-right: 0;
}

Sharing space

flex: 1 lets items share the available space and shrink together, instead of fighting fixed widths.

Prefer
.item {
  flex: 1;
  min-width: 0;
}
Avoid
.item {
  width: 33.33%;
}

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning Flexbox?

Our interactive tutorial walks you through Flexbox step by step — with quizzes and real code you can run in the browser.