gap property in flexbox
The gap property (and its variants row-gap and column-gap) creates consistent spacing between flex items without using margin. It's cleaner than manual margin calculations and doesn't create edge spacing. Supported in all modern browsers since 2020.
Using gap in flex containers
CSS
<!-- gap creates space between items -->
.container {
display: flex;
gap: 20px;
}
.item {
/* No need for margin -->
}
<!-- [Item] 20px [Item] 20px [Item] -->
<!-- No gap at edges -->
/* row-gap and column-gap for separate control -->
.container {
display: flex;
flex-wrap: wrap;
row-gap: 20px; /* space between rows -->
column-gap: 15px; /* space between columns -->
}
<!-- Gaps are different for rows and columns -->
/* Shorthand with two values -->
.container {
display: flex;
gap: 20px 15px; /* row-gap: 20px, column-gap: 15px -->
}
/* Single value applies to both -->
.container {
display: flex;
gap: 20px; /* both row and column gap -->
}
/* Using calc with gap */
.container {
display: flex;
gap: clamp(10px, 2vw, 30px);
/* Gap scales: 10px at narrow, 30px at wide */
}gap vs margin comparison
Method | Pros | Cons | Best For |
|---|---|---|---|
gap | Clean, no edges, modern | Not supported in IE11 | Modern projects |
margin | Wide browser support | Edge cases, needs hacks | Legacy browsers |
gap + fallback | Modern + fallback | More code | Broad compatibility |
CSS
<!-- Using gap (modern, clean) -->
.container {
display: flex;
gap: 20px;
padding: 20px;
}
.item {
/* Item margin not needed */
}
<!-- [padding] [item] gap [item] gap [item] [padding] -->
<!-- No item margins needed -->
/* Using margin (older approach) -->
.container {
display: flex;
margin: -10px; /* negative margin hack -->
padding: 20px;
}
.item {
margin: 10px; /* creates edge spacing too -->
}
<!-- [space] [item] margin [item] margin [item] [space] -->
<!-- Edge spacing included -->
/* Better: margin with flex-wrap -->
.container {
display: flex;
flex-wrap: wrap;
}
.item {
margin: 10px; /* spacing on all sides -->
flex: 0 0 calc(33.333% - 20px); /* account for margin -->
}
<!-- Still awkward, gap is cleaner -->
/* With gap fallback for older browsers -->
.container {
display: flex;
gap: 20px;
}
@supports not (gap: 20px) {
.item {
margin: 10px; /* fallback for browsers without gap -->
}
}
<!-- Modern browsers use gap, older use margin -->Practical gap patterns
CSS
<!-- Button group with gap -->
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.button {
flex: 0 0 auto;
padding: 10px 20px;
}
<!-- Buttons spaced evenly, wrappable -->
/* Grid of cards with gap -->
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 200px;
border: 1px solid #ddd;
padding: 20px;
}
<!-- Cards with consistent 20px spacing all around -->
/* Navbar with gap -->
.navbar {
display: flex;
align-items: center;
gap: 20px;
padding: 15px 20px;
background: #f5f5f5;
}
.logo {
flex: 0 0 auto;
}
.nav {
display: flex;
gap: 10px; /* inner gap for nav items -->
flex: 1;
justify-content: center;
}
.actions {
display: flex;
gap: 10px; /* inner gap for buttons -->
flex: 0 0 auto;
}
<!-- Logo, nav, actions all spaced properly -->
/* List with dividers -->
.list {
display: flex;
flex-direction: column;
gap: 0; /* no gap for dividers -->
}
.list-item {
padding: 15px;
border-bottom: 1px solid #eee;
}
.list-item:last-child {
border-bottom: none;
}
<!-- Items separated by dividers not gaps -->
/* Vertical spacing in column -->
.sidebar {
display: flex;
flex-direction: column;
gap: 15px;
padding: 20px;
}
.section {
padding: 15px;
background: #f5f5f5;
}
<!-- Consistent vertical spacing -->Responsive gap with clamp
CSS
<!-- Gap that scales with viewport -->
.container {
display: flex;
flex-wrap: wrap;
gap: clamp(10px, 2vw, 30px);
/* min: 10px, preferred: 2% of viewport, max: 30px */
}
<!-- Gap grows from 10px to 30px as viewport widens -->
/* Different gaps for rows and columns -->
.container {
display: flex;
flex-wrap: wrap;
row-gap: clamp(15px, 3vw, 40px); /* row spacing */
column-gap: clamp(10px, 2vw, 30px); /* column spacing -->
}
<!-- Row gap larger than column gap -->
/* Media query approach (traditional) -->
.container {
display: flex;
gap: 15px;
}
@media (min-width: 768px) {
.container {
gap: 20px;
}
}
@media (min-width: 1024px) {
.container {
gap: 30px;
}
}
<!-- Gap changes at breakpoints -->
/* With clamp, no media queries needed -->
.container {
display: flex;
gap: clamp(15px, 3vw, 30px);
/* Automatically adjusts -->
}gap with justify-content and align-items
CSS
<!-- gap works with alignment properties -->
.container {
display: flex;
justify-content: center; /* centers items -->
align-items: center; /* centers vertically -->
gap: 20px; /* gap between items -->
height: 200px;
width: 400px;
}
<!-- Items centered with spacing -->
/* Space-between with gap -->
.toolbar {
display: flex;
justify-content: space-between;
gap: 20px; /* minimum gap -->
}
<!-- Items spread apart, with at least 20px gap -->
/* Space-around with gap -->
.container {
display: flex;
justify-content: space-around;
gap: 20px; /* combines with space-around -->
}
<!-- Gap adds to space-around distribution -->
/* Flex items growing with gap -->
.row {
display: flex;
gap: 20px;
}
.col {
flex: 1; /* grows equally -->
}
<!-- Items grow, maintain 20px gaps -->
/* Complex layout with nested gaps -->
.page {
display: flex;
gap: 20px; /* outer gap -->
}
.sidebar {
display: flex;
flex-direction: column;
gap: 10px; /* inner gap for sidebar items -->
}
.content {
display: flex;
flex-direction: column;
gap: 15px; /* inner gap for content sections -->
}
<!-- Multiple gap levels -->
Note
`gap` provides clean spacing between flex items without edge margins. Use it on flex containers; it automatically applies to all items. For modern projects, prefer `gap` over margin; for older browser support, provide a margin fallback. Use `row-gap` and `column-gap` for different spacing in wrapped layouts.
Next
Individual item alignment: [align-self](/css/align-self).