---
title: "CSS gap Explained: Flexbox, Grid and Spacing"
url: https://theplusaddons.com/blog/css-gap/
date: 2026-11-09
modified: 2026-11-09
lang: en
author: "Aditya Sharma"
description: "Spacing between items looks like a small decision until a layout goes wrong. A row of cards has a stray gap at the end, a wrapped list of tags has..."
image: https://theplusaddons.com/wp-content/uploads/2026/11/css-gap-featured-1024x538.webp
word_count: 2167
---

# CSS gap Explained: Flexbox, Grid and Spacing

## 

- CSS gap sets gutters between rows and columns on the parent, and it does not add space before the first item or after the last one.
- MDN lists gap as Baseline widely available, with browser support since October 2017, and older stylesheets still accept grid-gap as an alias.
- Flexbox gap spaces both flex items and flex lines, and for rows the first value controls flex lines while the second controls items within a line.
- Grid gap makes spanning items include the gutters they cross, so a 3 by 3 grid with gap: 10px gives a two-column item a width of 210 pixels and a three-column item a width of 320 pixels.
- Elementor's Container element uses the same spacing idea through its Layout settings, where gap replaces per-widget margins and can be adjusted per breakpoint with the responsive icon.

Spacing between items looks like a small decision until a layout goes wrong. A row of cards has a stray gap at the end, a wrapped list of tags has uneven lines, or a grid needs different row and column spacing and the margin rules start fighting each other. For years the answer was a pile of margins with special cases for the first and last child.

The CSS `gap` property replaces that pile with one declaration on the parent. This guide covers the syntax, how it behaves in flexbox, grid and multi-column layouts, why it beats margins for most spacing, the situations where the visible space ends up larger than you set, and how the same idea appears in Elementor containers. Every visual below was rendered in Chrome.

 

Table Of Contents

## What The CSS gap Property Does

According to MDN, `gap` is a shorthand for `row-gap` and `column-gap`. It sets the gutters between rows and columns in grid, flex and multi-column layouts. The gap is a space between items only. It does not add space before the first item or after the last one.

![A flex row and a grid of four boxes each spaced with gap 16px](https://theplusaddons.com/wp-content/uploads/2026/11/gap-flex-grid.webp)The same gap: 16px on a flex container and on a grid container.

MDN lists `gap` as Baseline widely available, with support across browsers since October 2017, so you can use it in production. Early grid specifications called the property `grid-gap`, and browsers still accept that name as an alias, so older stylesheets keep working.

## Syntax: One Value Or Two

The shorthand accepts one or two values. One value sets both the row gap and the column gap. Two values set the row gap first and the column gap second. The default for both is `normal`, which computes to zero in flex and grid layouts.

`/* one value: rows and columns */
.cards { gap: 24px; }

/* two values: row-gap then column-gap */
.cards { gap: 32px 16px; }

/* longhand, same result */
.cards {
row-gap: 32px;
column-gap: 16px;
}`

![Three grids showing gap 10px, gap 10px 36px and separate row-gap and column-gap](https://theplusaddons.com/wp-content/uploads/2026/11/gap-row-col.webp)Row gap comes first in the two-value form: gap: 10px 36px means 10px between rows and 36px between columns.

A length or a percentage is allowed, and negative values are not. Percentages resolve against the content box of the container, which matters in one tricky case covered later in this guide.

## Why gap Beats Margin For Spacing

Margins belong to the child. Gap belongs to the parent. That difference is the whole story. When you space items with margins, every item carries the same margin, so the last one adds extra room that you then cancel with `:last-child` or a negative margin on the container. Wrapped rows make it worse because the first item of each line needs different treatment.

![A flex row with margin on every item leaves space at the end while a row using gap does not](https://theplusaddons.com/wp-content/uploads/2026/11/gap-vs-margin.webp)Margins leave trailing space on the last item. Gap puts space only between items.

| Task | With margins | With gap |
| ---- | ------------ | -------- |
| Even space between items | Margin on every item, then remove it from the first or last | One line on the parent |
| Wrapped rows | Extra rules or negative margins on the container | gap handles rows and columns together |
| Different row and column spacing | Separate margin-right and margin-bottom with edge cases | gap: 32px 16px |
| Reordering or hiding an item | The first or last child changes, so the edge rules break | Spacing follows the items that remain |
| Margin collapsing | Vertical margins can collapse in block flow | Gap never collapses |
A short comparison of spacing with margins and with gap.

There is one case where margin is still the right tool: when a single item needs its own extra space, such as a button pushed away from the rest with `margin-left: auto`. Use gap for the rhythm of the whole group and margin for one-off exceptions.

## Using gap In Flexbox

In a flex container, `gap` sets the space between flex items and between flex lines. MDN notes that which value applies to which direction depends on `flex-direction`. For rows, which is the default, the first value is the gap between flex lines and the second is the gap between items within a line. For columns the order flips. If you write a single value, the question disappears.

`.toolbar {
display: flex;
flex-wrap: wrap;
gap: 8px 12px; /* 8px between lines, 12px between items */
}`

![A wrapping row of rounded tag chips spaced with gap 8px 10px](https://theplusaddons.com/wp-content/uploads/2026/11/gap-wrap.webp)A wrapping tag list. Gap keeps line spacing and item spacing consistent without any margin rules.

This is the pattern behind tag clouds, filter bars, button groups and icon rows. Before flex gap had broad support, wrapped lists were the most common reason developers kept negative-margin hacks around. They are no longer needed.

## Using gap In Grid

In a grid, `gap` acts as if the grid lines gained thickness. MDN gives a useful example: with `gap: 10px` on a three by three grid of 100 pixel boxes, an item spanning two columns is 210 pixels wide, and one spanning all three is 320 pixels wide. Spanning items include the gutters they cross.

`.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: clamp(12px, 2vw, 28px);
}`

Pairing gap with `clamp()` keeps spacing proportional to the viewport without media queries. If you are new to that function, our guide to [CSS clamp](https://theplusaddons.com/blog/css-clamp/) explains how the three values work. For layouts that depend on the container instead of the viewport, see [CSS container queries](https://theplusaddons.com/blog/css-container-queries/).

## gap In Multi-Column Layouts And column-rule

In CSS multi-column layout, `gap` sets the gutter between columns. Its sibling `column-rule` draws a line in the middle of that gutter. MDN lists `column-rule` as Baseline widely available since March 2017, and the rule takes no layout space, so changing its width never moves your text.

`.article-columns {
column-count: 3;
column-gap: 40px;
column-rule: 2px solid #3a2ce0;
}`

![Three columns of text separated by a vertical rule drawn inside a 40px column gap](https://theplusaddons.com/wp-content/uploads/2026/11/gap-multicol.webp)A three-column text block. The rule is drawn in the middle of the 40px gap and adds no width.

MDN also documents a newer specification, CSS Gap Decorations, which extends the idea of rules between items to grid and flex layouts through the `rule` shorthand. MDN states that not every browser has implemented every part of it, so treat it as something to test per browser before relying on it, and keep `column-rule` in multi-column layouts as the safe choice today.

## Why The Visible Space Can Be Larger Than gap

MDN is explicit that the gap creates empty space with the size you set, much like an empty track, but the visible distance between items can be bigger. Three things add to it:

- **Margins and padding.** Item margins stack on top of the gap, so a 16 pixel gap plus 8 pixel margins gives 32 pixels between visible edges.- **Distributed alignment.** `justify-content: space-between` and `align-content` add free space between tracks beyond the gap value. The gap is the minimum, not the exact distance.- **Container size.** A percentage gap resolves against the container, so a container with no definite size can produce surprising results, as explained below.

When spacing looks wrong, open the browser inspector and hover the container. Browser developer tools can highlight gaps, which shows at once whether the extra space comes from the gap or from something else.

## Percentage Gaps And Container Size

A percentage gap is calculated against the content box of the container. MDN notes that this is well defined and consistent across layout modes when the container size is definite. When the container has no explicit height, grid and flex can behave differently. In a grid, cyclic percentages resolve against zero while sizing the container and then against its content box when laying out items. If a percentage gap looks odd, give the container a fixed size to test, or switch to a length such as `rem` or `clamp()`.

## Responsive Gaps With Custom Properties

Because gap is a single value, it is an ideal candidate for a design token. Store the spacing in a variable, then change the variable at breakpoints. Our guide to [CSS custom properties](https://theplusaddons.com/blog/css-custom-properties/) covers how variables inherit, which is what makes this pattern work across a whole page.

`:root { --space: 12px; }
@media (min-width: 768px) { :root { --space: 20px; } }
@media (min-width: 1200px) { :root { --space: 28px; } }

.grid { display: grid; gap: var(--space); }
.row { display: flex; gap: var(--space); }`

## Controlling Spacing In Elementor Containers

Elementor's Container element is built on flexbox and grid, so the same idea applies without writing CSS. Our walkthrough of [Elementor Flexbox containers](https://theplusaddons.com/blog/how-to-use-elementor-flexbox-containers/) notes that containers give you direction, alignment, justify, gap and wrap controls, and our comparison of [Flexbox and Grid containers](https://theplusaddons.com/blog/elementor-flexbox-vs-grid-container-differences/) helps you choose which one fits a layout. Setting the gap on the container is the same decision as writing `gap` on the parent in CSS, and it replaces per-widget margins in most cases.

- Select the container that holds your items and open the Layout settings in the Elementor editor.- Set the direction and enable wrap if the items should flow onto new lines.- Use the gap control to set the space between items. Set one value for even spacing, or set row and column gaps separately if the layout needs it.- Preview at tablet and mobile widths and adjust the gap per breakpoint using the responsive icon.- Remove leftover widget margins that were added to fake the spacing before, so they do not stack on top of the gap.

For anything the container controls do not cover, add one line of custom CSS to the container: `gap: 24px 12px;`. For the full list of container options, see the Elementor help page for [the Container element](https://elementor.com/help/container-element/).

## Real Layout Examples Using gap

Three patterns cover most everyday work. Each one replaces a set of margin rules with a single declaration on the parent.

### A Responsive Card Grid

A grid of cards that fills the available width and wraps by itself needs only `auto-fill` or `auto-fit` columns and a gap. There are no first-row or last-column rules to write, and the spacing stays equal in both directions.

`.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}`

### A Navigation Bar

A horizontal menu is a flex row with a gap. Because the gap sits only between items, the bar stays visually centred and the first and last links line up with the edges of the container.

`.nav {
display: flex;
align-items: center;
gap: 28px;
}
.nav .push { margin-left: auto; } /* one-off exception */`

### A Form Row

Form fields often sit in pairs that collapse to a single column on small screens. A grid with two columns and a smaller row gap handles it, and you only change the column template inside a media query.

`.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px 20px;
}
@media (max-width: 600px) {
.form-row { grid-template-columns: 1fr; }
}`

## How gap Works With Alignment Properties

Gap and alignment cooperate. The gap sets the minimum space between tracks or items, and the alignment properties decide what happens to any leftover room in the container. With `justify-content: space-between` on a flex row, the browser first honours the gap and then spreads the remaining free space between the items. That is why a 16 pixel gap can look like 80 pixels on a wide screen.

If you want the space between items to stay exactly as written, leave the alignment at its default of `flex-start` and let the container size itself to the content, or cap the container width. If you want items pushed to opposite ends with a safe minimum distance between them, combine `space-between` with a gap, which gives you both behaviours at once.

## Browser Developer Tools For Debugging Gaps

Modern browser developer tools can overlay the gaps of a flex or grid container directly on the page. MDN's own gap examples suggest using the Inspector in the developer tools and hovering the container to see the real gaps. Use that overlay whenever spacing feels off. It separates three questions quickly: is the gap what you set, is something adding margin, or is an alignment property distributing extra room.

## Common gap Mistakes

| Symptom | Likely cause | Fix |
| ------- | ------------ | --- |
| Space is bigger than the gap value | Item margins or space-between alignment add to it | Remove the margins or change justify-content |
| No space appears | The parent is not flex, grid or multi-column | Set display: flex or grid on the parent |
| Wrapped rows have no vertical space | Only a column value was set | Use gap with two values or add row-gap |
| Percentage gap looks inconsistent | Container has no definite size | Use a length unit or fix the container size |
| Divider line missing between columns | column-rule not set, or not a multi-column container | Add column-rule on a multi-column container |
Quick troubleshooting for gap.

## Putting It Together

Reach for `gap` first whenever you space items inside a flex, grid or multi-column parent. Use one value for even spacing, two values when rows and columns differ, keep it in a custom property so breakpoints stay simple, and treat margin as the exception for one-off adjustments. The result is less CSS, no first-child and last-child special cases, and layouts that survive reordering.

If you build with Elementor and want richer layouts than plain containers give you, such as grids, carousels and animated lists, the widgets in The Plus Addons for Elementor use the same spacing principles and expose them as simple controls.

[Explore The Plus Addons for Elementor](https://theplusaddons.com/pricing/)

## Suggested Reading

- [CSS clamp explained](https://theplusaddons.com/blog/css-clamp/)- [CSS container queries](https://theplusaddons.com/blog/css-container-queries/)- [CSS custom properties](https://theplusaddons.com/blog/css-custom-properties/)- [How to use Elementor Flexbox containers](https://theplusaddons.com/blog/how-to-use-elementor-flexbox-containers/)- [Elementor Flexbox vs Grid container](https://theplusaddons.com/blog/elementor-flexbox-vs-grid-container-differences/)