Lesson 9 of 30
gap started as a grid-only property, then landed in flexbox too — and quietly retired a whole category of margin-based spacing hacks along the way.
9 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
Before gap was available in flexbox, spacing a row of flex items with margin commonly required an extra step. What was it, and why?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Spacing a row of flex items used to be more annoying than it should have been. Margins on children are the obvious tool, but margin applies to every side you set it on — put margin-right on every item and you get an unwanted extra margin hanging off the last item too, pushing the container's effective width out or breaking alignment against its edge. Fixing that meant reaching for :not(:last-child) to strip the margin from the final item, or a negative margin on the container to cancel out the edge overflow — small, easy-to-forget patches layered on top of a property that was never really about spacing between things in the first place.
gap solves this directly: it adds space strictly between items, and never at the outer edges of the container. No child-side margin, no :not() selector, no negative-margin cancellation trick. gap started as a Grid-only property (where "space between tracks" was always exactly what was needed) and later became standard in flexbox too, so the same property now works the same way in both layout modes.
/* Before gap: margin hacks */
.toolbar-old > * {
margin-right: 0.75rem;
}
.toolbar-old > *:last-child {
margin-right: 0;
}
/* With gap */
.toolbar {
display: flex;
gap: 0.75rem;
}
The gap version is shorter, and it stays correct automatically as buttons are added, removed, or reordered — there's no "last child" to special-case because gap was never adding an edge margin to begin with. The same property also splits into two: row-gap and column-gap, with gap as shorthand for both (gap: 1rem 0.5rem means row-gap: 1rem; column-gap: 0.5rem;), which is useful in a wrapping flex row or a grid where vertical and horizontal spacing genuinely need to differ.
gap does not work on plain block or inline layout. It only has an effect inside display: flex, display: grid, or multicol (column-count/column-width) containers — set it on a container with the default block layout and it's simply ignored, which is a real, common gotcha for anyone who assumes it's a general-purpose spacing property.gap was Grid-only first. If you're reading or maintaining older code, gap (or its earlier grid-specific names grid-gap/grid-row-gap/grid-column-gap) appearing only inside grid rules isn't a mistake — those are just the pre-flexbox-support names still working today for compatibility.gap only ever adds space between siblings inside the same flex/grid container — it can't add space between a container and something outside it, or push one specific item away from its neighbors asymmetrically; that's still a job for margin on that individual item.gap in flexbox specifically is newer than gap in grid. If a codebase needs to support genuinely old browsers, this is worth an @supports (gap: 1rem) check with the margin-based fallback still in place, rather than assuming gap in a flex container is safe everywhere gap in a grid container is."How would you space out a row of flex items without adding unwanted margin on the outer edges?" is a real, common warm-up question — naming gap directly (instead of describing the old :not(:last-child) margin trick as if it were still the best approach) signals current, hands-on CSS knowledge.