CSSGaps & Alignment in Flexbox

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

gap

Clean, no edge margins

Newer, less browser support

Modern layouts

margin

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).