Flexbox changed CSS layout forever. Before it, centering a div vertically was a rite of passage that required hacks involving display: table-cell, negative margins, or absolute positioning. Flexbox made all of that trivial โ and it's now supported in every modern browser with over 99% global coverage.
Whether you're building a navigation bar, a card layout, a form, or an entire page structure, Flexbox handles it elegantly. This guide provides a complete property reference, practical layout patterns, and a detailed comparison with CSS Grid. Plus, our visual Flexbox generator lets you experiment with every property interactively.
Flexbox operates along two axes:
The flex-direction property determines which direction is the main axis. Understanding these axes is crucial because every Flexbox property references one or the other.
.container {
display: flex; /* Enables flexbox */
/* or */
display: inline-flex; /* Inline-level flex container */
}
Defines the main axis direction.
| Value | Direction | Use Case |
|---|---|---|
row (default) | Left โ Right | Navigation bars, card rows, inline forms |
row-reverse | Right โ Left | RTL layouts, reversed ordering |
column | Top โ Bottom | Stacked cards, form fields, vertical menus |
column-reverse | Bottom โ Top | Chat messages (newest at top), reversed lists |
Controls whether items wrap to new lines when they exceed the container width.
| Value | Behavior |
|---|---|
nowrap (default) | All items on one line, items shrink if needed |
wrap | Items wrap to new lines |
wrap-reverse | Items wrap in reverse order |
flex-wrap: wrap for any layout where items might exceed the container width (tag lists, card grids, responsive layouts). The default nowrap causes items to shrink unexpectedly on small screens.
Distributes space along the main axis.
| Value | Behavior | Visual |
|---|---|---|
flex-start | Items packed to the start | [items......] |
flex-end | Items packed to the end | [......items] |
center | Items centered | [...items...] |
space-between | Equal space between items, no edge space | [item..item..item] |
space-around | Equal space around items | [.item..item..item.] |
space-evenly | Equal space everywhere | [..item..item..item..] |
Distributes space along the cross axis (for all items in a single-line container, or the line as a whole in a multi-line container).
| Value | Behavior |
|---|---|
stretch (default) | Items stretch to fill the container's cross dimension |
flex-start | Items aligned to the start of the cross axis |
flex-end | Items aligned to the end of the cross axis |
center | Items centered on the cross axis |
baseline | Items aligned by their text baselines |
Distributes space between flex lines (only works when flex-wrap: wrap and there are multiple lines). Similar to justify-content but for the cross axis.
.container {
gap: 16px; /* Row gap and column gap */
gap: 16px 8px; /* Row gap: 16px, Column gap: 8px */
row-gap: 16px;
column-gap: 8px;
}
The gap property is the modern way to add spacing between flex items. It replaces the old hack of adding margins to items. Supported in all modern browsers since 2021.
Changes the visual order of items without changing the HTML.
.item-first { order: -1; } /* Moves to the beginning */
.item-last { order: 1; } /* Moves to the end */
/* Default order is 0 */
Defines how much an item should grow relative to siblings when there's extra space.
.item { flex-grow: 0; } /* Default: don't grow */
.item { flex-grow: 1; } /* Grow equally with other grow-1 items */
.item { flex-grow: 2; } /* Grow twice as much as grow-1 items */
Defines how much an item should shrink when the container is too small.
.item { flex-shrink: 1; } /* Default: shrink equally */
.item { flex-shrink: 0; } /* Don't shrink (important for fixed-size elements) */
Sets the initial size of an item before growing/shrinking.
.item { flex-basis: auto; } /* Default: based on content or width */
.item { flex-basis: 200px; } /* Start at 200px */
.item { flex-basis: 0; } /* Start at 0, grow fills remaining space */
/* Recommended shorthand */
flex: none; /* 0 0 auto โ fixed size, no grow/shrink */
flex: 0 0 auto; /* Same as above */
flex: 1; /* 1 1 0% โ grow, shrink, start from 0 */
flex: auto; /* 1 1 auto โ grow, shrink, start from content */
flex: 0 1 auto; /* Default โ shrink if needed, don't grow */
flex: 1 for items that should fill available space equally. Use flex: none (or flex: 0 0 auto) for items that should maintain their natural size. Avoid using flex shorthand values with units (like flex: 1 200px) as this creates confusing behavior.
Overrides the container's align-items for a specific item.
.special-item {
align-self: flex-end; /* This item aligns to the bottom, others follow align-items */
}
.center-me {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* This is THE reason most developers love Flexbox */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 64px;
}
/* Logo on the left, nav links on the right */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1; /* Pushes footer to the bottom */
}
footer {
/* Footer stays at the bottom even with little content */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 300px; /* Grow, shrink, min-width 300px */
max-width: calc(50% - 8px); /* Max 2 per row */
}
.input-group {
display: flex;
gap: 0;
}
.input-group input {
flex: 1; /* Input takes all available space */
}
.input-group button {
flex: none; /* Button stays its natural size */
.media {
display: flex;
gap: 16px;
align-items: flex-start;
}
.media img {
flex: 0 0 64px; /* Fixed avatar size */
border-radius: 50%;
}
.media .content {
flex: 1; /* Text fills remaining space */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.page main {
display: flex;
flex: 1;
}
.page main article {
flex: 1; /* Main content */
}
.page main nav {
flex: 0 0 200px; /* Left sidebar */
order: -1; /* Visually first */
}
.page main aside {
flex: 0 0 200px; /* Right sidebar */
One of the most common questions in CSS layout is "should I use Flexbox or Grid?" The answer isn't either/or โ they're complementary tools designed for different problems.
| Scenario | Use | Why |
|---|---|---|
| Center one element | Flexbox | 2 lines of code, content-driven |
| Navigation bar | Flexbox | Single row, dynamic spacing |
| Card grid (equal columns) | Grid | Two-dimensional, equal column widths |
| Masonry/pinterest layout | Grid (masonry) | Row and column control needed |
| Form layout | Flexbox | Labels and inputs in rows |
| Page header + sidebar + content + footer | Grid | Two-dimensional grid template |
| Tag/chip list | Flexbox | Wrap, content-driven sizing |
| Dashboard with widgets | Grid | Named grid areas, span control |
| Button group | Flexbox | Single row, alignment |
| Image gallery | Grid | Equal columns and rows |
| Responsive card layout | Either | Grid for strict columns, Flexbox for fluid wrapping |
| Modal/dialog centering | Flexbox | Simple centering, overlay |
In practice, most modern websites use both. A common pattern:
/* Page structure with Grid */
body {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
min-height: 100vh;
}
/* Components within use Flexbox */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
.form-row {
display: flex;
gap: 12px;
align-items: center;
}
Think of it this way: Grid for the macro layout, Flexbox for the micro layout. Grid defines where sections go on the page; Flexbox arranges items within those sections.
flex-basis: auto when items have complex content โ The browser must measure content before calculating layout, which can cause layout thrashingflex: 1 instead of flex: 1 1 0% โ They're equivalent, but the shorthand is cleanermin-width: 0 on flex items with long content โ Without it, items won't shrink below their content size, causing overflowgap instead of margins โ Cleaner, no margin collapse issues, works with flex-wrapflex-wrap: wrap over media queries when possible โ Items naturally reflow without breakpoint-specific rulesmin-width: auto by default, which means they won't shrink below their content size. If a flex item contains a long word or fixed-width element, it may overflow the container. Fix this with min-width: 0 (or overflow: hidden).
Flexbox is supported in all modern browsers with over 99% global support. The only considerations:
Flexbox is an essential tool for modern CSS layout. Its strength lies in handling one-dimensional layouts with dynamic content โ centering, distributing space, and responsive reflow. Combined with CSS Grid for two-dimensional layouts, you have everything needed to build any layout without hacks or workarounds.
Our visual Flexbox generator lets you experiment with every property interactively โ see the layout update in real-time as you adjust properties, and get clean, copy-paste CSS for your project.
Interactive Flexbox generator โ adjust properties, see live preview, copy production-ready CSS.
Open Flexbox Generator โFlexbox (Flexible Box Layout) is a CSS layout module that provides a more efficient way to arrange, align, and distribute space among items in a container. It works in one dimension (either a row or a column) and is ideal for component-level layouts.
Absolutely. In fact, this is the recommended approach for most projects. Use Grid for the overall page structure (header, sidebar, main content, footer) and Flexbox for arranging items within each section (navigation links, form fields, card content).
Flex items have min-width: auto by default, which prevents them from shrinking below their content size. Add min-width: 0 to the item (or overflow: hidden) to allow shrinking past the content width.
Set flex: 1 on all items (shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%). This makes each item take an equal share of available space regardless of content size.