Once you've turned a container into a flex container, the two properties you'll use constantly are justify-content and align-items. They're easy to mix up at first because they sound similar, but they control two different axes — understanding the main axis vs cross axis distinction makes the rest click into place immediately.
justify-content aligns items along the main axis (horizontal, by default). align-items aligns items along the cross axis (vertical, by default).
justify-content Values
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
.row { display: flex; justify-content: flex-start; } /* default: packed to the left */
.row { display: flex; justify-content: center; } /* packed together, centered */
.row { display: flex; justify-content: flex-end; } /* packed to the right */
.row { display: flex; justify-content: space-between; } /* first/last flush to edges, equal gaps between */
.row { display: flex; justify-content: space-around; } /* equal space around each item */
.row { display: flex; justify-content: space-evenly; } /* perfectly equal gaps everywhere, including edges */
space-between is the one used most often in real layouts — it's exactly what you want for a navbar with a logo on the far left and nav links on the far right, with nothing bunched in the middle. space-evenly is the subtle one: unlike space-around, which gives edge items only half the gap of inner items, space-evenly makes every gap, including the edges, exactly equal.
align-items Values
.row {
display: flex;
height: 120px; /* a taller container makes vertical alignment visible */
align-items: flex-start; /* items align to the top */
align-items: center; /* items vertically centered */
align-items: flex-end; /* items align to the bottom */
align-items: stretch; /* default: items stretch to fill the full height */
}
With align-items: stretch (the default), every item in the row grows to match the height of the tallest item or the container itself — which is why flex items often appear "full height" even when you didn't set a height on them explicitly. Switching to center is the single most common fix for the age-old "how do I vertically center this" problem in CSS.
Centering Both Ways at Once
.hero {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
This is the classic two-line solution to centering a single element — a modal, a loading spinner, a hero heading — both horizontally and vertically within its container, replacing much clunkier margin/positioning hacks from before flexbox existed.
