Setting display: flex on an element creates a flex container. Its direct children become flex items, automatically arranging themselves according to flexbox rules:
.container {
display: flex;
}
That's it. With one line, you get a flexible layout system that handles alignment, distribution, and responsive behavior.
The Flex Container
The container controls how items are arranged. Key properties:
flex-direction: Sets the main axis (row or column):
.container {
display: flex;
flex-direction: row; /* Default: horizontal */
}
Options: row, row-reverse, column, column-reverse.
justify-content: Aligns items along the main axis:
.container {
display: flex;
justify-content: center; /* Horizontally center (if row) */
}
Options: flex-start, flex-end, center, space-between, space-around, space-evenly.
align-items: Aligns items along the cross axis:
.container {
display: flex;
align-items: center; /* Vertically center (if row) */
}
Options: flex-start, flex-end, center, baseline, stretch (default).
The Two Axes
Flexbox works with two axes:
-
Main axis: Direction set by
flex-direction - Cross axis: Perpendicular to main axis
If flex-direction: row:
- Main axis = horizontal
- Cross axis = vertical
If flex-direction: column:
- Main axis = vertical
- Cross axis = horizontal
justify-content works on the main axis. align-items works on the cross axis. Understanding this is key to flexbox.
Flex Items
Individual items can control their behavior:
flex-grow: How much the item grows to fill space:
.item {
flex-grow: 1; /* Take up available space */
}
If all items have flex-grow: 1, they share space equally. If one has flex-grow: 2, it takes twice as much.
flex-shrink: How much the item shrinks when space is limited:
.item {
flex-shrink: 0; /* Don't shrink */
}
Default is 1 (items can shrink). Setting 0 prevents shrinking.
flex-basis: Initial size before growing/shrinking:
.item {
flex-basis: 200px; /* Start at 200px */
}
flex shorthand: Combines all three:
.item {
flex: 1 0 200px; /* grow shrink basis */
}
/* Common patterns: */
flex: 1; /* Equivalent to: 1 1 0 */
flex: 0 0 auto; /* Don't grow or shrink, use natural size */
Common Layout Patterns
Horizontal centering:
.container {
display: flex;
justify-content: center;
}
Vertical centering:
.container {
display: flex;
align-items: center;
height: 100vh;
}
Perfect centering (both axes):
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
Space between items:
.container {
display: flex;
justify-content: space-between;
}
Equal-width columns:
.container {
display: flex;
}
.item {
flex: 1; /* All items grow equally */
}
Sidebar + main content:
.container {
display: flex;
}
.sidebar {
flex: 0 0 250px; /* Fixed width, no grow/shrink */
}
.main {
flex: 1; /* Take remaining space */
}
Wrapping
By default, flex items stay on one line. flex-wrap allows wrapping:
.container {
display: flex;
flex-wrap: wrap; /* Items wrap to next line if needed */
}
Options: nowrap (default), wrap, wrap-reverse.
With wrapping, align-content controls space between lines:
.container {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
Gap Property
Modern flexbox supports gap for spacing between items:
.container {
display: flex;
gap: 20px; /* 20px between all items */
}
Before gap, you'd use margins on items, which created edge cases. gap is cleaner.
Flexbox vs Grid
Use flexbox for one-dimensional layouts (single row or column). Use grid for two-dimensional layouts (rows and columns simultaneously).
Flexbox: Navigation bars, centering, flexible components
Grid: Page layouts, complex 2D arrangements
They're complementary. A grid layout might contain flex containers, and vice versa.
Browser Support
Flexbox has excellent support (IE10+ with prefixes, all modern browsers unprefixed). For older browsers, use autoprefixer to add vendor prefixes automatically.
Common Pitfalls
Forgetting height for vertical centering:
/* Won't center vertically without height */
.container {
display: flex;
align-items: center;
}
/* Fixed */
.container {
display: flex;
align-items: center;
height: 100vh;
}
Mixing up justify-content and align-items: Remember: justify-content is main axis, align-items is cross axis. Which is which depends on flex-direction.
Not using flex shorthand: flex: 1 is clearer than flex-grow: 1; flex-shrink: 1; flex-basis: 0;
Responsive Flexbox
Change flex direction on smaller screens:
.container {
display: flex;
flex-direction: row;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
This pattern adapts horizontal layouts to vertical on mobile.
Accessibility
Flexbox can reorder items visually with order, but screen readers follow DOM order. Don't use visual reordering for critical content flow:
.item-1 { order: 2; } /* Visually second */
.item-2 { order: 1; } /* Visually first */
Screen readers still see item-1 first. If order matters semantically, change the HTML.
Debugging Flexbox
Browser DevTools show flexbox properties. In Chrome/Firefox, inspecting a flex container highlights the flex axes and shows space distribution.
Common debugging questions:
- Why isn't my item centering? Check height and axis direction.
- Why are items overflowing? Check
flex-wrapandflex-shrink. - Why is spacing uneven? Check
flex-growandflex-basisvalues.
Performance
Flexbox is fast. The browser's layout engine handles it efficiently. For large lists (hundreds of items), consider virtualization rather than avoiding flexbox.
Further Reading
CSS-Tricks' Complete Guide to Flexbox is the definitive visual reference.
MDN's Flexbox documentation covers all properties in detail.
Wes Bos's free What The Flexbox? course teaches flexbox through practical examples.
Flexbox simplified layouts that used to require floats and clearfix hacks.
0 comments