flex gaps & alignment precision
The gap property creates consistent spacing between flex items, replacing manual margin calculations. Combine gap with justify-content and align-items for precise alignment. Understanding these properties together is key to building clean, maintainable flex layouts.
gap vs margin for spacing
Approach | Pros | Cons | Best for |
|---|---|---|---|
| Clean, no edge margins | Newer, less browser support | Modern layouts |
| Wide support | Edge cases, double margins | Older browsers |
Combination | Fallback support | More complex | Broad compatibility |
CSS
/* gap creates space between items (not at edges) -->
.container {
display: flex;
gap: 20px;
}
.item {
/* No need for margin -->
}
<!-- [Item] gap [Item] gap [Item] -->
<!-- No extra space at edges! -->
/* Old approach with margin (has edge spacing) -->
.container {
display: flex;
margin: -10px; /* negative margin hack -->
}
.item {
margin: 10px;
/* Creates spacing at edges too -->
}
<!-- [space] [Item] [space] -->
/* gap is much cleaner -->
.flex {
display: flex;
gap: 16px;
padding: 16px;
}
.item {
/* Just the item, no margin math needed -->
}
/* Separate row and column gaps -->
.grid-flex {
display: flex;
flex-wrap: wrap;
row-gap: 20px; /* space between rows -->
column-gap: 16px; /* space between columns -->
}
/* Responsive gaps -->
.container {
display: flex;
gap: clamp(10px, 2vw, 30px);
/* Scales gap based on viewport -->
}Alignment combinations
CSS
<!-- Center items both horizontally and vertically -->
.container {
display: flex;
justify-content: center; /* horizontal center -->
align-items: center; /* vertical center -->
width: 400px;
height: 200px;
}
<!-- [Item centered] -->
/* Space-around with centered items -->
.container {
display: flex;
justify-content: space-around;
align-items: center;
gap: 20px;
}
<!-- [Item] space [Item] space [Item] -->
<!-- All vertically centered -->
/* Space-between with top alignment -->
.container {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20px;
}
<!-- [Item] ........... [Item] -->
<!-- Items at top, spread horizontally -->
/* Complex alignment with flex-start and flex-end -->
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 20px;
height: 60px;
}
.logo { flex: 0 0 auto; }
.nav { flex: 1; }
.actions { flex: 0 0 auto; }
<!-- [Logo] [Nav spans] [Actions] -->Individual item alignment with align-self
CSS
<!-- All items centered by default -->
.container {
display: flex;
align-items: center;
gap: 20px;
}
.item {
/* All items centered -->
}
<!-- One item breaks alignment -->
.item.top {
align-self: flex-start;
/* This item goes to top, others stay centered -->
}
.item.bottom {
align-self: flex-end;
/* This item goes to bottom -->
}
.item.stretch {
align-self: stretch;
/* This item stretches full height -->
}
<!-- Practical example: card with stretching action button -->
.card {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 15px;
}
.card-header {
flex: 0 0 auto;
}
.card-content {
flex: 1;
}
.card-footer {
display: flex;
gap: 10px;
}
.btn-primary {
flex: 1;
align-self: stretch;
/* Button fills available height -->
}justify-items and align-content (multi-line flex)
CSS
<!-- Wrap items across multiple lines -->
.container {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
align-content: center;
height: 400px;
width: 100%;
}
.item {
flex: 1 1 200px;
}
<!-- justify-content: distributes items horizontally -->
<!-- align-content: distributes line groups vertically -->
/* Different align-content values -->
.flex-start {
align-content: flex-start;
/* Lines start at top -->
}
.flex-end {
align-content: flex-end;
/* Lines start at bottom -->
}
.space-between {
align-content: space-between;
/* First line at top, last at bottom, space between -->
}
.space-around {
align-content: space-around;
/* Even space around line groups -->
}
.stretch {
align-content: stretch;
/* Lines stretch to fill height -->
}Practical alignment patterns
CSS
<!-- Button group: items spread with gap -->
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.button {
flex: 0 0 auto;
padding: 10px 20px;
}
<!-- Tabs: items centered, gap between -->
.tabs {
display: flex;
gap: 5px;
justify-content: center;
border-bottom: 1px solid #ddd;
}
.tab {
flex: 0 0 auto;
padding: 12px 20px;
cursor: pointer;
}
.tab.active {
border-bottom: 2px solid blue;
}
<!-- List with dividers -->
.list {
display: flex;
flex-direction: column;
gap: 0;
}
.list-item {
padding: 15px;
border-bottom: 1px solid #eee;
}
.list-item:last-child {
border-bottom: none;
}
<!-- Header with spacer -->
.header {
display: flex;
align-items: center;
gap: 20px;
padding: 15px 20px;
}
.logo { flex: 0 0 auto; }
.nav-items { flex: 0 1 auto; }
.spacer { flex: 1; }
.actions { flex: 0 0 auto; }
<!-- [Logo] [Nav] [spacer] [Actions] -->Note
`gap` is the modern way to space flex items. It's cleaner than margin, doesn't affect edges, and works great with `justify-content` and `align-items` for precise layouts.
Next
Advanced flex layouts: [flex nesting & complex layouts](/css/flex-advanced).