Flex Container Properties
Master the full set of properties applied to the flex container — flex-direction, flex-wrap, flex-flow, justify-content, align-items, align-content, and gap — including every value option and exactly what it does visually.
Once an element is a flex container, a handful of properties on that container control the entire layout: which direction items flow, whether they wrap onto new lines, how they're spaced along the main axis, and how they're aligned along the cross axis. These are the properties you'll reach for constantly, so it's worth learning every value precisely rather than guessing by trial and error.
flex-direction and flex-wrap
flex-direction sets the main axis and the direction items are placed in. row (default) lays items left to right; row-reverse lays them right to left; column lays items top to bottom; column-reverse lays them bottom to top. Reversing doesn't just visually flip items — it also reverses their order in terms of layout direction, which matters for keyboard focus order in some cases (the DOM order, and therefore tab order, stays the same).
By default, flex items try to fit onto a single line, shrinking if necessary — they never wrap. flex-wrap: wrap changes that, allowing items to flow onto additional lines when they run out of room on the main axis. flex-wrap: nowrap is the default (everything squeezes onto one line). flex-wrap: wrap-reverse wraps, but stacks the extra lines in the opposite cross-axis direction.
flex-flow is a shorthand that combines flex-direction and flex-wrap into one declaration, e.g. flex-flow: row wrap.
• flex-direction: row | row-reverse | column | column-reverse • flex-wrap: nowrap (default) | wrap | wrap-reverse • flex-flow: <flex-direction> <flex-wrap> (shorthand)
justify-content — aligning along the main axis
justify-content distributes space between and around items along the main axis. flex-start (default) packs items at the start of the main axis. flex-end packs them at the end. center groups them together in the middle. space-between spreads items so the first sits flush at the start, the last sits flush at the end, and remaining space is divided evenly between the items in the middle — with no space at the outer edges. space-around gives every item equal space on both its sides, which means the gap between two items ends up looking twice as big as the gap at the very start or end (since neighboring items' side-spaces combine). space-evenly fixes that visual inconsistency by making every gap — including the two outer edges — exactly equal.
• flex-start: items pushed to the start of the main axis • flex-end: items pushed to the end of the main axis • center: items grouped in the center of the main axis • space-between: equal gaps between items, no gap at the outer edges • space-around: equal space on each side of every item (outer edges look half as spaced as between items) • space-evenly: every gap, including the outer edges, is exactly equal
align-items, align-content, and gap
align-items aligns items along the cross axis, one line at a time. Its values mirror justify-content in spirit: stretch (default — items stretch to fill the cross axis if they have no explicit size), flex-start, flex-end, center, and baseline (aligns items so their text baselines line up, useful when items have different font sizes).
align-content is easy to confuse with align-items, but it only matters when there are multiple lines of wrapped items — it controls how those lines, as a group, are spaced within the container's cross axis, using the same keyword set as justify-content (flex-start, flex-end, center, space-between, space-around, space-evenly, plus stretch). With only one line of items, align-content has no visible effect.
gap (along with the longhands row-gap and column-gap) inserts fixed space between flex items without needing margins on individual items, and — unlike margins — it doesn't add extra space at the outer edges of the container. It works with flex-wrap too, applying consistently between rows and columns.
• align-items: stretch (default) | flex-start | flex-end | center | baseline • align-content: controls spacing between *wrapped lines* — has no effect with a single line • gap: shorthand for row-gap and column-gap; no space added at container edges
The core container property set
.container {
display: flex;
flex-direction: row; /* row | row-reverse | column | column-reverse */
flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
justify-content: center; /* flex-start | flex-end | center | space-between | space-around | space-evenly */
align-items: center; /* stretch | flex-start | flex-end | center | baseline */
align-content: space-between; /* only visible with multiple wrapped lines */
gap: 16px; /* row-gap column-gap, or one value for both */
}Code Examples
The logo and nav links sit at opposite ends of the bar (space-between), everything is vertically centered regardless of differing heights (align-items: center), and gap adds breathing room between links without affecting the outer edges.
With identical items in each row: row-a has zero space at the outer edges; row-b has space at the edges but it looks half as wide as the gaps between items; row-c makes every gap, edges included, perfectly equal. This distinction is one of the most commonly tested Flexbox details — memorize it by the visual result, not just the name.
flex-wrap allows cards to drop to new lines once they run out of horizontal room. align-content: flex-start packs the resulting rows toward the top of the container instead of spreading them out, which matters once the container is taller than its content.
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24px;
}.row-a { display: flex; justify-content: space-between; }
.row-b { display: flex; justify-content: space-around; }
.row-c { display: flex; justify-content: space-evenly; }.card-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
align-content: flex-start;
}justify-content values along the main axis
Dashes represent empty space along the main axis. Note how space-around leaves smaller gaps at the edges than between items, while space-evenly equalizes all gaps.
flex-start: [A][B][C]--------------
center: -------[A][B][C]-------
flex-end: --------------[A][B][C]
space-between: [A]------[B]------[C]
space-around: -[A]----[B]----[C]-
space-evenly: --[A]----[B]----[C]--Important Rules
justify-content always operates on the main axis; align-items always operates on the cross axis align-content only has a visible effect when flex-wrap produces more than one line gap never adds space outside the outermost items, unlike margins on individual items align-items: stretch is the default, which is why flex items often appear to auto-fill the container's cross-axis size unless they have an explicit height/width
Real-world usage
Space-between is the classic choice for navbars (logo on one side, links on the other) and for spreading form buttons to opposing corners. space-evenly shows up in evenly distributed icon rows or pagination controls where visual consistency at the edges matters. gap has effectively replaced margin-based spacing tricks for flex layouts across modern codebases..grid { display: flex; align-content: space-between; /* expecting rows to spread out */ }.grid { display: flex; flex-wrap: wrap; align-content: space-between; }
Without flex-wrap, all items stay on a single line, so align-content has nothing to act on — it only affects the spacing of multiple wrapped lines..list { display: flex; justify-content: center; } /* trying to vertically center items */.list { display: flex; align-items: center; }
Vertical centering in a default row layout is a cross-axis operation, so it's align-items, not justify-content, that should be used.
[Multiple Choice] A flex container has five items and applies justify-content: space-around. Compared to space-between on the same items, what changes visually? A. space-around removes all spacing between items entirely B. space-around adds equal space on both sides of every item, making the outer edge gaps look smaller than the gaps between items C. space-around behaves identically to space-between in every case D. space-around only works when flex-wrap is set to wrap
B. space-around adds equal space on both sides of every item, making the outer edge gaps look smaller than the gaps between items — space-around gives each item equal space on both sides. Because adjacent items' side-spaces combine, the gap between two items ends up looking twice as wide as the half-space left at the outer edges — unlike space-between, which leaves zero space at the edges.
Build a .pricing-row flex container that holds three pricing cards, wraps on small screens, keeps a consistent 24px gap in both directions, and centers the cards as a group when they wrap onto multiple lines..pricing-row { display: flex; flex-wrap: wrap; gap: 24px; justify-content: center; align-content: center; }
You'll need flex-wrap: wrap, gap: 24px, and align-content (not align-items) for the multi-line centering.