Use Flexbox when you want items to share space along a row or column. Use Grid when the relationship between rows and columns matters. You can combine them: a grid of cards can contain a flex toolbar inside each card.
The same items in Flexbox and Grid
HTML and CSS
HTML
<h2>Flexbox</h2>
<div class="flex">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
<h2>Grid</h2>
<div class="grid">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
CSS
.flex {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.flex > div {
flex: 1 1 100px;
}
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1rem;
}
/* Optional presentation */
.flex > div,
.grid > div {
background: #dbeafe;
padding: 1rem;
}
h2 {
font-size: 1.1rem;
}
Edit HTML or CSS to update the preview as you type. Copy code snippet copies the selected tab. Preview spacing and font defaults are not included.
In the flex example, wrapping creates independent lines. The fourth item can fill its own line without matching the columns in the line above. In the grid example, it belongs to the first column of the next row, so its edges stay aligned with the item above it. Resize the preview or copy it into a narrow browser window to compare.
Choose from the layout you need
A navigation bar, a row of buttons, or a label next to a control often needs one-dimensional space distribution. Flexbox is a good fit. A calendar, an aligned gallery, or a page with shared column tracks often needs Grid.
Flexbox can wrap into several rows; “one-dimensional” describes how each line is laid out independently. Grid can also be used for a single row. Neither is restricted to large or small interfaces.
Sizing and alignment
flex-basis, flex-grow, and flex-shrink distribute space between flex items. grid-template-columns defines shared grid tracks, and grid-auto-rows sizes rows created by auto-placement.
Both models support alignment. justify-content distributes space along Flexbox’s main axis or around Grid’s columns. align-items aligns items across a flex line or within the block direction of grid areas. Grid also has justify-items for alignment within each area.
A practical combination
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
gap: 1rem;
}
.card-actions {
display: flex;
flex-wrap: wrap;
gap: .5rem;
}
The card grid responds to available width. The actions inside a card wrap independently. Give children room to shrink, check long words and URLs, and preserve the reading order: visual reordering does not necessarily change keyboard or screen-reader order.
Try it
Add a fifth item to both examples. Then change the grid to two columns. Identify which layout keeps matching column boundaries between rows. Use that behavior to decide what your interface needs.
Sources
MDN: Flexbox and MDN: Grid explain the models and their relationship.