Flexbox, short for the Flexible Box Layout, is a CSS layout method built for arranging items along a single row or column. Instead of manually calculating widths, margins, and floats, you tell the browser how you want the available space distributed, and Flexbox figures out the rest.
This guide covers how Flexbox works from the ground up: every container property, every item property, common real-world patterns, the differences from CSS Grid, and a cheat sheet reference for quick lookup.
What is CSS Flexbox?
Flexbox, short for the Flexible Box Layout, is a one-dimensional layout method for arranging items in a row or column. It is the tool you reach for whenever a layout is fundamentally one-dimensional: a navigation bar, a row of buttons, a set of form fields, or a group of cards that all need to line up and stay evenly spaced no matter how much content each one holds.
.container { display: flex; }
Flexbox Syntax Basics
Flexbox works with two roles: a flex container and its flex items. You create a flex container by setting display: flex on a parent element, every direct child of that element automatically becomes a flex item.
Once display: flex is set, two axes come into play, and almost every Flexbox property is really just a question of which axis it controls.
- The main axis: the primary direction items are laid out along. Horizontal by default (
flex-direction: row). - The cross axis: runs perpendicular to the main axis. Vertical by default.
Properties that start with justify- work along the main axis. Properties that start with align- work along the cross axis. That single rule of thumb resolves most Flexbox confusion.
Flex Container Properties
These properties are set on the parent element, the flex container itself.
flex-direction
Sets which way the main axis runs, and therefore how items are ordered.
.container { flex-direction: row; /* default, left to right */ flex-direction: row-reverse; flex-direction: column; /* top to bottom */ flex-direction: column-reverse; }
flex-wrap
By default, flex items try to fit on a single line, shrinking if needed. flex-wrap lets them drop onto new lines instead.
.container { flex-wrap: nowrap; /* default */ flex-wrap: wrap; flex-wrap: wrap-reverse; }
flex-flow is shorthand for flex-direction and flex-wrap together, for example flex-flow: row wrap;.
justify-content
Aligns items along the main axis, controlling how extra space is distributed between and around them.
.container { justify-content: flex-start; /* default */ justify-content: flex-end; justify-content: center; justify-content: space-between; justify-content: space-around; justify-content: space-evenly; }
align-items
Aligns items along the cross axis, for a single row this usually means vertical alignment.
.container { align-items: stretch; /* default, items fill the cross axis */ align-items: flex-start; align-items: flex-end; align-items: center; align-items: baseline; }
align-content
Controls spacing between wrapped lines along the cross axis. It only has a visible effect when flex-wrap: wrap is set and there is extra space across multiple lines.
gap
Adds consistent spacing between flex items without needing margin hacks, and it does not add space before the first or after the last item.
.container { gap: 16px; /* row and column gap */ gap: 16px 24px; /* row-gap column-gap */ }
Tip: Prefer gap over margins for spacing between flex items. It is simpler, and it will not accidentally push the whole row off-center.
Flex Item Properties
These properties are set on the children, the flex items themselves.
flex-grow, flex-shrink, and flex-basis
These three are the most misunderstood part of Flexbox, so it is worth being precise about what each one actually does.
| Property | What it controls | Default |
|---|---|---|
| flex-basis | The item's starting size, before leftover space is distributed | auto |
| flex-grow | How much of the leftover space the item can absorb, relative to siblings | 0 |
| flex-shrink | How much the item can shrink if there is not enough space | 1 |
Most of the time you will use the flex shorthand rather than setting all three separately:
.item { flex: 1; /* grow: 1, shrink: 1, basis: 0% */ flex: 0 1 auto; /* default values, written out */ flex: 2; /* grow twice as fast as a sibling with flex: 1 */ }
A common source of bugs: giving two items flex: 1 makes them grow equally from a basis of 0, not from their content size. If you want items to start at their natural width and only share leftover space, use flex: 1 1 auto instead.
order
Changes the visual order of an item without touching the HTML. Default is 0, lower values appear first.
.item-featured { order: -1; /* moves this item to the front */ }
align-self
Overrides align-items for a single item, useful when one item in a row needs different cross-axis alignment than the rest.
.item { align-self: flex-end; }
Flexbox vs CSS Grid
This is the question that comes up more than any other, and the short answer is that they solve different shaped problems. Flexbox is one-dimensional, it lays items out along a single row or column. Grid is two-dimensional, it lays items out along rows and columns at the same time.
| Flexbox | CSS Grid | |
|---|---|---|
| Dimensions | One (row or column) | Two (rows and columns) |
| Best for | Navbars, toolbars, button groups, form rows | Page layouts, card grids, dashboards |
| Sizing driven by | Content, items can grow or shrink | Explicit tracks you define upfront |
| Item order control | order property | Explicit placement (grid-column, grid-row) |
In practice, most real interfaces use both. A common pattern is Grid for the overall page skeleton, with Flexbox handling alignment inside individual sections, like the contents of a header or a card.
Real-World Flexbox Recipes
A responsive navbar
Logo on the left, links on the right, all vertically centered, with the links wrapping on small screens.
.navbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; padding: 16px 24px; }
Equal-height cards in a row
Without Flexbox, cards with different amounts of content end up different heights. With align-items: stretch (the default), every card automatically matches the tallest one in its row.
.card-row { display: flex; gap: 20px; } .card { flex: 1; display: flex; flex-direction: column; }
Perfectly centering content
The two-line answer to a question that trips up a lot of beginners.
.center { display: flex; justify-content: center; align-items: center; }
A sticky footer
Keeps the footer at the bottom of the viewport even when there is not enough content to push it there naturally.
body { display: flex; flex-direction: column; min-height: 100vh; } main { flex: 1; /* pushes footer down by absorbing leftover space */ }
Nested Flexbox Patterns
Flex items can themselves be flex containers, which is how most real components are actually built. A card row is a flex container, and each card inside it can be its own flex container arranging an icon, a title, and a button.
.card { display: flex; flex-direction: column; gap: 12px; } .card-footer { display: flex; justify-content: space-between; align-items: center; }
Each nested flex container has its own independent main and cross axis, set with its own flex-direction. Nothing about the parent's axis carries down to the child.
Skip the syntax, build it visually
Prefer to drag, drop, and see the CSS update live? The Flexbox Generator gives you the same properties from this guide with a real-time preview, plus CSS, Tailwind, and Bootstrap output.
Open the Flexbox Generator →CSS Flexbox Cheat Sheet
A compact reference for the properties covered above.
| Property | Applies to | Common values |
|---|---|---|
| display: flex | Container | flex, inline-flex |
| flex-direction | Container | row, row-reverse, column, column-reverse |
| flex-wrap | Container | nowrap, wrap, wrap-reverse |
| justify-content | Container | flex-start, center, space-between, space-around, space-evenly |
| align-items | Container | stretch, flex-start, center, flex-end, baseline |
| align-content | Container | flex-start, center, space-between, stretch |
| gap | Container | any length value |
| order | Item | any integer |
| flex-grow | Item | 0 (default), 1, 2... |
| flex-shrink | Item | 1 (default), 0, 2... |
| flex-basis | Item | auto, 0, any length |
| flex | Item | shorthand for grow, shrink, basis |
| align-self | Item | overrides align-items for one item |
FAQ
What is CSS Flexbox used for?
Flexbox is a one-dimensional layout method for arranging items in a row or a column. It is used for things like navigation bars, button groups, card rows, form controls, and any layout where items need to grow, shrink, or align along a single axis.
Is Flexbox still relevant?
Yes. Flexbox is a stable, well supported CSS module and remains the standard tool for one-dimensional layouts such as navbars, toolbars, and content that needs to align or distribute along a single row or column. CSS Grid complements it for two-dimensional layouts, it does not replace it.
Is Flexbox hard to learn?
The core ideas, the main axis, the cross axis, and a handful of container properties, can be learned in an afternoon. Most of the difficulty people run into comes from a small number of common mix-ups, like confusing flex-grow with flex-basis, which this guide covers directly.
Flexbox vs CSS Grid, which is better?
Neither is universally better, they solve different problems. Flexbox is built for one-dimensional layout (a single row or column), while Grid is built for two-dimensional layout (rows and columns together). Use Flexbox for things like navbars and button groups, and Grid for full page layouts and card grids.
Can you use Flexbox and CSS Grid together?
Yes, and it is common practice. A typical pattern is to use Grid for the overall page structure, then use Flexbox inside individual grid cells to align and distribute smaller groups of content, like the contents of a card or a toolbar.
Why use Flexbox instead of Grid?
Choose Flexbox when your layout is fundamentally a single row or column and items need to grow, shrink, or wrap based on available space, such as a navigation bar, a row of tags, or a set of form fields. It requires less setup than Grid for these one-dimensional cases.
What is the difference between the main axis and the cross axis?
The main axis is the direction items are laid out along, controlled by flex-direction, row by default. The cross axis runs perpendicular to it. Properties like justify-content work along the main axis, while align-items and align-content work along the cross axis.
Does Flexbox work in all browsers?
Flexbox has full support in every modern browser, including Chrome, Firefox, Safari, and Edge. It has been safe to use without fallbacks for years, the only exception is very old browser versions that are no longer in meaningful use.
What is the difference between flex-grow and flex-basis?
flex-basis sets an item's starting size before any leftover space is distributed. flex-grow controls how much of that leftover space the item is allowed to absorb, relative to its siblings. An item can have a small flex-basis and still end up large if it has a high flex-grow value.
How do I center something with Flexbox?
Set display: flex on the parent, then justify-content: center to center along the main axis and align-items: center to center along the cross axis. Using both together centers an item both horizontally and vertically.