Gap vs Margin in Layouts
Prefer gap in flex/grid for inter-item spacing — no collapse surprises, no last-child hacks, and when margin is still the right tool.
- css
- gap
- margin
- layout
For years, flex and grid spacing meant margins on children plus :last-child resets or lobotomized owl selectors. gap puts spacing on the container between items (and tracks). Less CSS, fewer edge bugs, clearer intent.
Docs: MDN gap, Flexbox gap, Grid gap.
gap on the container
.toolbar {
display: flex;
align-items: center;
gap: 0.75rem;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
gap: 1rem 1.25rem; /* row column */
}
gap only creates space between items/tracks — not outside the first/last item. Outer padding still belongs on the container or a parent.
.panel {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem; /* outer inset */
}
Margin pain that gap removes
/* Old pattern */
.list > * + * {
margin-top: 1rem;
}
/* Or */
.card {
margin-right: 1rem;
}
.card:last-child {
margin-right: 0;
}
Problems:
- Forgetting the last-child reset
- Margins collapsing in block flow (not with flex/grid items the same way, but mixed layouts confuse)
- Asymmetric spacing when wrapping
- Negative margin tricks to cancel grid gutters
/* Modern */
.list {
display: flex;
flex-direction: column;
gap: 1rem;
}
When margin still wins
| Need | Tool |
|---|---|
| Space between flex/grid siblings | gap |
Push one item away (margin-inline-start: auto) |
margin |
Overlap / pull (margin-top: -0.5rem) |
margin |
| Space outside a component relative to random neighbors | margin (or parent gap) |
| First-line indent / float tricks | margin |
.nav {
display: flex;
gap: 1rem;
}
.nav__auth {
margin-inline-start: auto; /* absorbs free space — not a gap job */
}
Stacking with nested layouts
.card {
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 1rem;
}
.card__meta {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
Parent gap + child gap compose cleanly. Parent gap + child margins often double-space.
Gap and percentage / wrapping
gap is accounted for when sizing flex/grid tracks. If columns suddenly wrap “too early,” check gap + padding + borders — not only minmax.
Interview out-loud
“gap sets spacing between items in flex and grid containers without last-child hacks. It doesn’t replace padding for outer insets or auto margins for pushing items. I default to gap for lists, toolbars, and grids, and use margin for positioning within free space or for relationships outside a flex/grid context.”
Footguns
- Putting gap on a non-flex/grid container (ignored for normal block).
- Using margin and gap for the same relationship.
- Expecting gap to collapse like block margins.
- Forgetting older browser requirements if you still support them — know your baseline.
row-gap/column-gaptypos when only one axis should space.
Migrating a legacy list
/* Before */
.menu a { display: block; margin-bottom: 0.5rem; }
.menu a:last-child { margin-bottom: 0; }
/* After */
.menu {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
Same visual, fewer edge cases when items are conditionally rendered (no last-child thrash). For inline chips that used horizontal margins, flex + gap also removes the doubled gap problem when wrapping.
Gap in multi-column and masonry-like grids
Grid gap applies between tracks. If you previously used negative margin tricks to cancel outer gutters, delete them — gap never adds outer space. Outer inset is padding on the container or margin on the container relative to its parent.
Related
Further reading
Related guides
- CSS Box ModelContent, padding, border, margin, box-sizing, and how the math actually works for layout and overflow.
- CSS Grid FundamentalsTwo-dimensional layout with tracks, gaps, placement, fr units, and when grid beats flex for page scaffolding.
- CSS Grid vs Flexbox When to UseOne-dimensional flex vs two-dimensional grid — decision rules for navs, card grids, page shells, and nested layouts.
- Display Block Inline Flex GridHow display changes layout participation — block vs inline vs inline-block, and when flex/grid formatting contexts take over.
- Flexbox FundamentalsFlex container vs items, main vs cross axis, grow/shrink/basis, alignment, wrapping, and the bugs that show up in real layouts.