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
gapinstead of margins — it only adds space between items, avoiding edge spacing issues. - Use the
flexshorthand —flex: 1is cleaner than setting grow, shrink and basis separately. - Avoid fixed widths on flex items — let
flex-basisandflex-growhandle sizing for responsiveness. - Prefer
flex-wrap: wrapfor responsive layouts instead of media queries for item sizing. - Use
align-items: centerfor vertical centering — it is the most reliable approach. - Combine with
min-width: 0on 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: flexon the items instead of the container. - Forgetting that
align-contentrequiresflex-wrap: wrapto have any effect. - Using fixed
widthon flex items instead offlex-basis. - Not setting
min-width: 0on items that might overflow their flex container. - Overusing
!importantto override flex item sizing instead of understanding the flex algorithm. - Applying Flexbox properties to the wrong axis — forgetting that
flex-directionswaps the main and cross axes. - Ignoring accessibility — Flexbox changes visual order with
orderbut 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:
- Start with
display: flexandjustify-content— see how items distribute along one axis. - Add
align-items— understand the cross axis and how it relates toflex-direction. - Experiment with
flex-direction: column— see how the axes swap. - Try
flex-wrap: wrapandgap— build a multi-line layout. - Play with
flex-grow,flex-shrinkandflex-basis— understand how items share space. - Build real layouts: a navbar, a card row, a centered hero, a sidebar layout.
- 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.