This article covers how to use the CSS gap property to space elements apart.
The short answer: inside a Flexbox or Grid container, create spacing with gap rather than margin. You avoid the extra space at the edges, and you never have to cancel the margin on the last item.
▼margin versus gap
margin |
gap |
|
|---|---|---|
| Declared on | The children | The container |
| Space at the edges | Added | None |
| Fixing the last item | Cancel it with :last-child |
Not needed |
| Space between wrapped rows | Needs separate handling | Same value applies |
| Margin collapsing | Happens | Does not happen |
Sponsored
Basic use of the gap property
What gap does
gap sets the spacing between items inside a Flexbox or Grid container. It replaces the pattern of adding margins to each child and then removing the one on the end.
Basic syntax
.container {
display: flex; /* or display: grid; */
gap: 20px;
}
A worked example
With the markup and CSS below, 20px of space appears between each box, and none at the outer edges.
<div class="container">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
</div>
.container {
display: grid;
gap: 20px;
}
.box {
background-color: #f0f0f0;
padding: 10px;
}
Different spacing for rows and columns
gap sets both the row and column spacing at once. To set them separately, use row-gap and column-gap.
.container {
display: grid;
/* 30px between rows, 10px between columns */
row-gap: 30px;
column-gap: 10px;
}
The shorthand takes two values. The order is row first, then column.
.container {
/* first value is rows, second is columns */
gap: 30px 10px;
}
That ordering differs from margin and padding, which run top, right, bottom, left. Getting it backwards is an easy mistake to make.
When gap has no effect
gap only applies when the parent is flex, grid or a multi-column container.
If it appears to do nothing, check that the parent actually has display: flex or display: grid. A forgotten display declaration is the usual cause.
.container {
/* without this, gap is ignored */
display: flex;
gap: 20px;
}
Spacing between display: block or inline-block elements cannot be created with gap. Use margin there, or make the parent a flex container.
Responsive layouts with Flexbox and gap
Wrapping columns
Combining flex-wrap with gap gives you a responsive grid with very little code. The number of columns changes with the available width.
.container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.box {
flex: 1 0 200px;
}
flex: 1 0 200px means each box starts at 200px, may grow to fill the row, and will not shrink below that. Combined with flex-wrap, items move to the next row when they no longer fit.
Sponsored
A mosaic layout with Grid and gap
Placing images in a grid
gap makes it straightforward to lay images out in a grid.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 10px;
}
auto-fit with minmax() lets the browser decide how many columns fit, so no media queries are required. Each column is at least 250px wide and shares the remaining space equally.
Summary
This article covered creating spacing with the gap property in Flexbox and Grid layouts.
The main reason to prefer it over margin is that the spacing sits between items only, never at the edges. That removes an entire category of small layout corrections.
Using gap also avoids the problem where space-between leaves the last row’s items pushed to opposite edges. Aligning to the start and letting gap create the spacing is more reliable than using space-between and correcting it afterwards.
If you would rather not hand-write this layer of CSS, recent CSS Grid updates and how to apply them covers what the layout system now handles for you.