Defining CSS gaps

When creating grid, flexbox, and multi-column layouts using CSS gap properties, you can define and control gaps between columns and rows.

While the margin and padding properties specify visual spacing around individual boxes, using the properties in the CSS gaps module, you can specify spacing between adjacent boxes in layouts that have gutters and gaps.

This guide explains column and row gaps in different layout types, how to define gaps, and how to use percentages as a gap value.

Understanding gaps

While margin and padding can specify spacing around individual boxes, it's sometimes more convenient to specify spacing between adjacent boxes within a given layout. This is particularly true when the spacing between sibling boxes differs from the spacing between the first or last box and the container's edge. The gap property, and its row-gap and column-gap constituent properties, provide this functionality for grid, flexbox, and multi-column layouts.

A gap is either a column gap or a row gap. Their definitions vary by layout type. For all layout types, any gap disappears when it coincides with a fragmentation break.

Grid container gaps

In the context of a grid container, row gaps and column gaps refer to the gutters between grid rows and grid columns, respectively. The width of the gaps makes the affected grid lines behave as though they acquired thickness: the grid track between two grid lines is the space between the gutters that represent them. By default, the width of the gap is 0 in both directions.

For the purpose of track sizing, each gutter is treated as an extra, empty, fixed-size track of the specified size. A grid item that spans multiple rows or columns also spans the gutters between them.

For example, if gap: 20px is set on a 4x4 grid of 100px by 100px boxes, the grid would be 460px by 460px. While each box is 100px by 100px, a grid item that spans two horizontal rows has a height of 220px. If it spans three, its height is 340px. If it spans all four, its height is 460px.

Gutter gaps set the minimum spacing between items: additional spacing may be added by justify-content and align-content property values, increasing the size of the corresponding gaps.

Gutters appear only between tracks of the implicit grid. If a grid is fragmented between tracks, no gutter spacing is added between those tracks. There is no gutter before the first track or after the last track. If a track is collapsed, it has no gutter.

Flex container gaps

Flex containers are created by setting display to flex or inline-flex on an element containing multiple children. By default, flex items are laid out in a single, non-wrapping row. The default gap between adjacent flex items and, if wrapping, between adjacent columns or rows, is 0. Whether a flex container with multiple items has columns, rows, or both depends on the flow and wrapping set using the flex-flow shorthand.

You can add gaps between adjacent flex items along the main axis. If the flex-flow property is set to row wrap or row-reverse wrap, column gap refers to the gutter between adjacent flex items and row gap refers to the gutter between flex rows. If flex-flow is set to column wrap or column-reverse wrap, row gap refers to the gutter between adjacent flex items and column gap refers to the gutter between flex rows.

Multi-column gaps

Multi-col containers are block-level elements with more than one column created by setting the column-count to a value greater than 1. By default, columns are laid out in a single row, with a 1em wide column gap between adjacent columns. The row gap is the gutter between rows of column boxes established by setting a column-height that requires columns to wrap, creating additional rows.

Using the gap shorthand

The row-gap property sets the size of the gap (gutter) between a adjacent rows within a container. The column-gap property sets the size between a container's columns. Each property value can be specified as a <length>, a <percentage>, or the keyword normal. Percentage values are calculated against the content box size of the container element for that dimension.

The gap shorthand defines gaps between both rows and columns and accepts one or two values. The default value is normal for both sub-properties. If only one value is declared, it applies to both row and column gaps. If two values are declared, the first sets the row-gap value and the second sets the column-gap.

The effect of the definition depends on whether the container uses grid, flexbox, or multi-column layout.

You can add visible separators to gaps; these are called gap decorations. If you add decorative rules for gaps between columns, rows, or both, they appear in the middle of their gap but have no effect on the size of the gap, nor do they effect the size of the container. These gap decorations are added to the otherwise "empty space" by using the rule shorthand or its constituent properties.

Gaps in grid layouts

In grid containers, the gap property defines the size of the gutters between vertical and horizontal tracks. The shorthand property is specified as a value for <'row-gap'>, followed optionally by a value for <'column-gap'>. If only one value is declared, it applies to both row and column gaps.

In this example, we create a grid container with seven columns:

css
.container {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

Select different gap values to see how they change the spacing between rows and columns:

Gaps in flexbox layouts

In flex containers, the gap property defines the space between both flex items and flex lines. Whether the first value sets the gap between flex items or between flex lines depends on the direction in which the flex items are laid out.

Flex items are laid out in rows or columns depending on the value of the flex-direction property. If set to row or row-reverse, the first value defines the gap between flex lines, and the second value defines the gap between adjacent flex items within each line. If only one value is included, it applies to both gaps.

If the flex-direction is set to column or column-reverse, the first value defines the gap between adjacent flex items within a flex line, and the second value defines the gaps between flex lines. Again, if only one value is included, it applies to both gaps.

In this example, we create a flex container and allow the flex items to wrap:

css
.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 300px;
  height: 500px;
}

Select different gap and flex-direction values to see how they change the spacing between flex items and flex lines:

Gaps in multi-column layouts

In CSS multi-column layouts, the gap property defines the gutter between columns and between rows of columns. The first value defines the gap between rows of column boxes, if multiple rows are established by the column-height property. The second value defines the gap between adjacent column boxes.

In this example, we create a multi-col container using the columns shorthand property, setting a maximum of seven columns and a minimum column width of 1em. A column height of 2.35em enables the creation of additional rows. We also add a thin decorative rule in the middle of the gap using the rule property:

By default, there is a 1em gap between rows and columns. Change this by selecting different gap values:

The gutters may appear larger than the specified gap size because the letters don't fill the allotted space. The decorative rule appears in the middle of the gap, either 0.25em or 1.5em from the block and inline starts of the column and row's content depending on the setting selected. The extra whitespace is at block- and inline-end, making the gaps look larger than they are.

Specifying gap values as percentages

When a container has a fixed size, column and row gaps specified as percentages are calculated relative to the width and height of the container, respectively.

In this example, the size of the container is set. Select different gap sizes as percentage values, and change the layout type to see how the gaps are calculated relative to the container's size. Column gaps of 1% and 5% are 3px and 15px wide, respectively. Row gaps of 1% and 5% are 6px and 30px tall, respectively. These gap sizes apply even if the contents overflow the container.

css
.container {
  width: 300px;
  height: 600px;
  background-color: #eee;
  rule: 1px dotted #666;
}

Note that if you set the gap property to a single percentage value, the row gap is twice the size of the column gap because the container is twice as tall as it is wide.

If we don't have a defined height or width for the container, the behavior of percentage gap values is very different. If the container has a fixed width, percentage gap values are predictable. If the container is auto‑sized, percentage gaps could create a circular dependency: the gaps depend on the container's size, but the container's size depends on the gaps. Browsers treat percentage gap values as auto (effectively 0) during intrinsic sizing.

css
.container {
  background-color: #eee;
  rule: 1px dotted #666;
  height: auto;
  width: auto;
}

In the example, the width of the container is constrained by the containing block, while the height is not.

As percentage values are treated as auto during intrinsic sizing for gaps in grid layout, the gap is collapsed until the size of the container is determined. This means the size of the container is determined based solely on the dimensions of the content. If the example renders six rows of grid cells, there will be five row gaps, meaning the last row of grid items will overflow the background by either 5% or 25%, depending on whether the gap is set to 1% or 5%.

In flexbox layouts, the percentage gaps are treated as 0 or ignored during intrinsic sizing. The gap is applied only after sizing. As the container's block size is auto, the percentage row gaps resolve against 0; so 1% or 5% of 0 is 0. Percentage values are effectively ignored - the row-gap is 0 for both flexbox and multi-col layouts.

See also