
Using the CSS gap Property in Flexbox Without Margin Hacks
For years, spacing sibling elements inside flex containers required cumbersome workarounds: applying margin-right to children paired with :last-child reset selectors, or applying negative margins on outer parent wrappers to compensate for child outer gutters.
With cross-browser adoption of the gap, row-gap, and column-gap properties in CSS Flexible Box Layout, gutter spacing can now be declared cleanly directly on the flex container itself.
Example
Consider a responsive navigation bar and a multi-line tag list. With traditional margin hacks, wrapping rows produced awkward bottom and side overhangs:
<nav class="toolbar">
<button type="button" class="btn">Cut</button>
<button type="button" class="btn">Copy</button>
<button type="button" class="btn">Paste</button>
</nav>
<ul class="badge-list">
<li>Architecture</li>
<li>Accessibility</li>
<li>Performance</li>
<li>Algorithms</li>
</ul>
Implementation
Using modern CSS Flexbox, gutters only apply between adjacent flex items, eliminating the need for any margin resets on edge elements:
.toolbar {
display: flex;
align-items: center;
gap: 12px;
}
.badge-list {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
margin: 0;
row-gap: 10px;
column-gap: 16px;
}
.badge-list li {
padding: 4px 12px;
background: var(--lightgray);
border-radius: 4px;
}
// Progressive test for Flexbox gap support
const isFlexGapSupported = () => {
const flex = document.createElement('div');
flex.style.display = 'flex';
flex.style.flexDirection = 'column';
flex.style.rowGap = '1px';
flex.appendChild(document.createElement('div'));
flex.appendChild(document.createElement('div'));
document.body.appendChild(flex);
const isSupported = flex.scrollHeight === 1;
flex.parentNode.removeChild(flex);
return isSupported;
};
Main Point: The gap property in CSS Flexbox provides clean, symmetric spacing between items that automatically respects wrapping lines without negative margin hacks.
Credits
Photo by Simone Hutsch on Unsplash