CSS Flexbox Guide: Properties, Patterns, and Practical Examples
Before Flexbox, centering a div was a running joke in web development. Vertical centering required hacks involving negative margins, table-cell display modes, or absolute positioning with transforms. Flexbox solved that problem and many others. It is the standard way to build one-dimensional layouts in CSS, and every front-end developer needs to know it well.
The Core Mental Model
Flexbox works on two axes. The main axis runs in the direction set by flex-direction, which defaults to row (left to right). The cross axis runs perpendicular to it (top to bottom by default). Every Flexbox property either distributes space along the main axis or aligns items along the cross axis. Once you internalize this, the entire API clicks.
You create a flex container by setting display: flex on a parent element. Its direct children automatically become flex items.
.container {
display: flex;
}
/* All direct children are now flex items */
Container Properties (The Parent)
flex-direction
This sets the main axis direction. Your options are row (default), row-reverse, column, and column-reverse. Setting column flips everything: the main axis becomes vertical, so justify-content distributes space vertically instead.
flex-wrap
By default, flex items try to fit on one line (nowrap). Set flex-wrap: wrap to let items flow onto new lines when the container is too narrow. I use this constantly for responsive card grids.
justify-content
This distributes space along the main axis. flex-start (default) packs items to the start, and flex-end packs them to the end. center does what you'd expect. The spacing values are where it gets interesting: space-between pins the first and last items to the edges with equal gaps between them, space-around adds equal space around each item (with half-space at the edges), and space-evenly gives you perfectly equal space everywhere including the edges.
align-items
This aligns items along the cross axis. stretch is the default, making items fill the container height. You also get flex-start, flex-end, and center. The one worth calling out is baseline, which aligns text baselines across items. Really useful when you have mixed-size elements sitting next to each other.
gap
Sets the spacing between flex items. Use gap: 16px instead of adding margins to individual items. It avoids the classic "last-item margin" problem. All modern browsers support it.
Item Properties (The Children)
flex-grow
Controls how much an item grows relative to its siblings when there is extra space. The default is 0, meaning the item won't grow at all. If one item has flex-grow: 2 and another has flex-grow: 1, the first item gets twice as much of the available space.
flex-shrink
Controls how much an item shrinks when the container is too small. The default is 1, so items shrink equally. Set it to 0 on elements that must not shrink, like a logo or icon.
flex-basis
The initial size of the item before grow and shrink kick in. You can use any length value (200px, 30%) or auto, which uses the item's intrinsic size. Think of it as a replacement for width in flex layouts.
The flex Shorthand
flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%. It means "take up all available space equally." flex: 0 0 200px means "fixed at 200px, never grow or shrink." I use these two constantly. Learn the shorthand and you'll write fewer lines of CSS.
align-self
This overrides the container's align-items for a single item. I reach for it when I need to push one element to the bottom of a card while the rest stay at the top.
Practical Patterns
1. Perfect Centering
.center-me {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Two lines of intent (center on both axes), plus a height to center within. Done.
2. Navigation Bar
.navbar {
display: flex;
align-items: center;
gap: 24px;
padding: 16px 24px;
}
.navbar .logo { margin-right: auto; }
/* Logo stays left, nav links cluster right */
The margin-right: auto trick pushes everything after the logo to the far end of the container. Simple, no extra wrapper needed.
3. Equal-Height Cards
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 300px; /* grow, shrink, min 300px */
display: flex;
flex-direction: column;
}
.card .content { flex: 1; }
.card .footer { margin-top: auto; }
Cards wrap responsively, maintain equal height per row, and the footer sticks to the bottom regardless of content length.
4. Input with Button
.input-group {
display: flex;
}
.input-group input { flex: 1; }
.input-group button { flex-shrink: 0; }
The input fills all available space, the button stays at its natural width.
Want to try every Flexbox property in real time? Adjust values and see the layout update instantly.
Try the Free Flexbox PlaygroundFlexbox vs. Grid: When to Use Which
Flexbox is one-dimensional. It controls either a row or a column, not both at once. CSS Grid is two-dimensional, controlling rows and columns simultaneously. I use Flexbox for navigation bars, button groups, form rows, and single-line layouts. Grid makes more sense for page scaffolding, dashboards, and anything that requires alignment across both axes. The two compose well together: Grid for the page structure, Flexbox inside each grid cell.
When you're ready for two-dimensional layouts, check out the CSS Grid Generator.
Browser Support
All major browsers have supported Flexbox since 2015. The gap property for flex containers reached full support in 2021 (Safari 14.1+). No vendor prefixes needed in 2026. If you're stuck supporting extremely old browsers, check CSS compatibility, but for any modern project, Flexbox just works.
Frequently Asked Questions
What is the difference between Flexbox and CSS Grid?
Flexbox is one-dimensional: it lays items out along a single axis (row or column). CSS Grid is two-dimensional: it controls both rows and columns simultaneously. Use Flexbox for navbars, button groups, and single-axis layouts. Use Grid for page layouts and dashboards. They work well together, with Grid handling page structure and Flexbox inside each cell.
How do I center an element with Flexbox?
Set the parent to display: flex; justify-content: center; align-items: center; and give it a height. justify-content centers along the main axis (horizontal by default), and align-items centers along the cross axis (vertical). This is the most reliable centering technique in CSS.
Why does flex: 1 work for filling remaining space?
flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%. The flex-grow: 1 tells the item to absorb all available space. If multiple items have flex: 1, they share the space equally. flex-basis: 0% means the size calculation starts from zero, so the available space is distributed purely by the grow factor.