CSS Gap Decorations: Complete Guide for Web Developers
Guide · June 2026

CSS Gap Decorations:
The Complete Guide for Web Developers

Chrome 149 just shipped CSS gap decorations stable — the new native way to style gaps in Grid, Flexbox, and Multi-Column layouts. Learn every property, see real code examples, and understand browser support from a senior frontend developer.

Oleg Maximov June 3, 2026 16 min read

Introduction

For years, web developers have used column-rule to draw elegant lines between columns in multi-column layouts — but CSS Grid and Flexbox had no equivalent. Want a subtle line between grid cells or flex items? You had to reach for borders, pseudo-elements, box-shadows, or background hacks. Every approach was fragile, hard to maintain, and broke when the layout changed.

CSS Gap Decorations (shipped stable in Chrome 149 on June 2, 2026) change all of that. They introduce four new properties — gap-rule-width, gap-rule-color, gap-rule-style, and gap-rule-break — that let you style the gaps between items in any gap-based layout: Grid, Flexbox, and Multi-Column.

In this guide, I'll show you everything you need to know: the problem gap decorations solve, the complete syntax for every property, before-and-after comparisons, real-world patterns, and progressive enhancement strategies for production use.

The Problem: Styling Gaps Before Gap Decorations

Before Chrome 149, if you wanted a visual separator — a line, a dotted border, a colored stripe — between items in a CSS Grid layout, you had to use workarounds:

Hack #1: Background-Color on the Grid Container

The most common trick was to set a background-color on the grid container and give items a margin or padding to create the appearance of a gap line:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px; /* gap creates the visible "rule" */
  background: #ddd; /* background shows through the gap */
}
.grid-item {
  background: white; /* items cover the rest */
}

This worked but was extremely limited — you could only create solid, single-color "lines" that had to match the gap size. Dotted, dashed, or multi-color lines? Not possible.

Hack #2: Borders and Pseudo-Elements

Another approach was adding border-right and border-bottom to every grid item, then adjusting with negative margins or box-shadow:

.grid-item {
  border-right: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  margin-right: -1px;
  margin-bottom: -1px;
}

This produced edge-aligned lines (not centered in the gap), broke when items wrapped to a new row, and required careful negative-margin math that differed per browser. Flexbox with wrapping was even worse — the borders never aligned correctly when the row count was uneven.

Hack #3: Box-Shadow for Simulated Lines

Some developers used box-shadow to draw "lines" between items:

.flex-item {
  box-shadow: -1px 0 0 0 #ccc; /* left "line" */
}
.flex-item:first-child {
  box-shadow: none; /* remove from first item */
}

This worked for simple cases but failed with wrapping, was invisible on items with their own shadows, and consumed GPU memory for every item.

💡 The Takeaway: Every pre-gap-decoration approach was a hack. CSS gap decorations solve all of these problems with four declarative properties that work natively with the gap-based layout model.

The Solution: CSS Gap Decoration Properties

CSS gap decorations provide four properties that mirror the column-rule pattern but work across all gap-based layouts:

Property Description Values
gap-rule-width Thickness of the rule drawn in the gap 1px, 0.5rem, thin, medium, thick
gap-rule-color Color of the rule Any valid CSS color
gap-rule-style Line style of the rule solid, dashed, dotted, double, groove, ridge, inset, outset, none, hidden
gap-rule-break How the rule behaves at gap intersections avoid, column, page, always

There's also a shorthand gap-rule that combines them:

/* Shorthand: gap-rule: <width> <style> <color> */
.container {
  display: grid;
  gap: 1rem;
  gap-rule: 1px solid #94a3b8;
}

The gap-rule shorthand follows the same pattern as border and column-rule: width, style, then color — all optional but typically all three are provided.

Gap Decorations in Grid Layouts

The most immediate use case for gap decorations is CSS Grid. Let's look at a typical card grid with a subtle separator:

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;

  /* Draw a thin, light rule in every gap */
  gap-rule-width: 1px;
  gap-rule-color: #e2e8f0;
  gap-rule-style: solid;
}

.card {
  padding: 1.5rem;
  border-radius: 8px;
  background: #fff;
}

That's it — three CSS properties and your card grid has a clean, centered separator between every row and column. No borders, no pseudo-elements, no box-shadow hacks. The rule is drawn in the center of each gap, automatically.

Want a dashed line instead? Change one property:

.card-grid {
  gap-rule-style: dashed;
  gap-rule-color: #94a3b8;
}

Want a bold accent line between items? Easy:

.card-grid {
  gap-rule-width: 3px;
  gap-rule-color: #0f766e;  /* teal accent */
  gap-rule-style: double;
}

💡 Best Practice: Keep gap decorations subtle. A 1px solid line with low-contrast color (like #e2e8f0 on a white background) provides visual separation without overwhelming the content. Save bold colors and thick rules for decorative sections like featured product grids.

Gap Decorations in Flexbox Layouts

Gap decorations work equally well in Flexbox. This was previously the hardest layout mode to style gap separators for, because flex items wrap unpredictably and border hacks always broke on wrap:

.nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;

  /* Vertical rules between rows, horizontal rules between columns */
  gap-rule: 1px dotted #cbd5e1;
}

.nav-item {
  padding: 0.5rem 1rem;
}

Before gap decorations, creating dotted separators between flex items in a wrapping layout was effectively impossible with CSS alone. JavaScript-based solutions had to measure positions and inject border elements — and they broke on resize. Now it's three lines of CSS.

Here's a practical real-world pattern — a horizontal toolbar with separators:

.toolbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;

  gap-rule-width: 1px;
  gap-rule-color: #d1d5db;
  gap-rule-style: solid;
  gap-rule-break: avoid; /* don't split a rule across wrapped rows */
}

The gap-rule-break: avoid setting is particularly useful in flexbox because it prevents orphaned rule fragments when items wrap to a new line.

Gap Decorations in Multi-Column Layouts

Multi-column layouts already had column-rule, but gap decorations provide additional capabilities. The gap-rule-break property, for example, gives you finer control over how rules behave across column breaks:

.article-text {
  columns: 3;
  column-gap: 2rem;

  /* Equivalent to column-rule but with gap-rule-break control */
  gap-rule-width: 1px;
  gap-rule-color: #cbd5e1;
  gap-rule-style: solid;
  gap-rule-break: column; /* break the rule at column boundaries */
}

In multi-column layouts, gap decorations are effectively a superset of column-rule — they offer the same styling options plus gap-rule-break for controlling rule continuity.

Before and After: A Complete Comparison

Let's see a real example — a product grid with four columns and separator lines. Here's the old approach vs the new approach:

Old Approach (Borders on Items)

.product-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}

.product-item {
  border-right: 1px solid #e2e8f0;
  border-bottom: 1px solid #e2e8f0;
  padding: 1.5rem;
}

/* Last column — remove right border */
.product-item:nth-child(4n) {
  border-right: none;
}

/* Last row — remove bottom border */
.product-item:nth-last-child(-n+4) {
  border-bottom: none;
}

This works only when you know the column count (4) at authoring time. With auto-fill or auto-fit, the column count changes at different viewport widths — and the nth-child formulas break.

New Approach (Gap Decorations)

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem 1.5rem;

  /* Single declaration */
  gap-rule: 1px solid #e2e8f0;
}

.product-item {
  padding: 1.5rem;
}

Three CSS lines replace ten. The gap decoration automatically handles wrapping, responsive column counts, and spacing. It draws the line in the center of each gap, not at the edge of items — which looks much more polished.

💡 Pro tip: Pair gap decorations with padding inside items rather than margin. The gap property handles item spacing, and gap decorations draw in the gap center. Using margins on items inside a gap-based layout can offset where the rule appears — stick with padding for consistent results.

The gap-rule-break Property: Controlling Rule Continuity

One of the most powerful aspects of gap decorations is gap-rule-break, which controls what happens to the rule at intersections and break points.

Value Behavior Best For
avoid Rule avoids breaking; may skip the break point entirely Flex layouts where you don't want orphaned rule fragments between wrapped items
column Rule breaks at column boundaries Multi-column text layouts, grid layouts with explicit column boundaries
page Rule breaks at page boundaries (paged media) Print layouts, PDF generation
always Rule always breaks at every intersection Grid layouts where each cell is visually independent, data tables

The avoid value is especially useful in wrapping flexbox layouts where you want lines only between items on the same row:

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  gap-rule: 1px solid #e2e8f0;
  gap-rule-break: avoid; /* no orphaned rules */
}

Real-World Patterns

Pattern 1: Data Table with Row and Column Lines

Data tables benefit enormously from gap decorations. Instead of complex border management:

.data-table {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 0;
  gap-rule: 1px solid #e2e8f0;
  gap-rule-break: always;
}

.table-header,
.table-row {
  display: contents; /* flatten into the grid */
}

.table-cell {
  padding: 0.75rem 1rem;
}

With gap: 0 the lines connect at corners, creating a full grid of cells. With a small gap like 2px and gap-rule-break: always, you get separated cells with their own rule lines — perfect for card-based tables.

Pattern 2: Navigation Menu with Vertical Separators

.main-nav {
  display: flex;
  align-items: center;
  gap: 0;
  gap-rule: 1px solid #334155;
  gap-rule-break: avoid;
}

.nav-link {
  padding: 0.5rem 1.25rem;
}

Classic nav separator pattern — lines between items, no line before the first or after the last item — without first-child/last-child border gymnastics.

Pattern 3: Card Grid with Accent Separators

.featured-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  gap-rule-width: 2px;
  gap-rule-color: linear-gradient(to bottom, #0f766e, #14b8a6);
  gap-rule-style: solid;
}

Gap decorations support gradient colors via the gap-rule-color property — truly something no hack could achieve. A gradient rule draws a smooth color transition across the gap.

Browser Support and Progressive Enhancement

As of June 2026, CSS gap decorations are supported in:

Firefox and Safari have the feature under consideration for their upcoming releases. The CSS Working Group specification is at Editor's Draft stage under the CSS Backgrounds and Borders Module Level 4.

Progressive Enhancement Strategy

Because gap decorations are purely decorative, they're a perfect candidate for progressive enhancement. The core layout — the gap property itself — works in all modern browsers. The gap decoration rules only appear in browsers that support them:

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;        /* Works everywhere */

  /* Enhancement — ignored in unsupported browsers */
  gap-rule: 1px solid #e2e8f0;
}

In unsupported browsers, the layout renders normally — items are still spaced, the grid is still responsive. The decorative lines simply don't appear. There's no breakage, no overlapping content, no layout shift. This is the ideal progressive enhancement scenario.

For a deeper look at other modern CSS layout features, see my guides on CSS Container Queries, CSS Anchor Positioning, and CSS View Transitions API.

Limitations and Considerations

While gap decorations are a huge improvement, there are a few things to be aware of:

Summary

CSS gap decorations are a long-overdue addition to the CSS layout toolkit. They bring the elegant column-rule pattern to Grid and Flexbox, eliminating years of border hacks and pseudo-element workarounds.

The key takeaways:

Start using gap decorations in your projects today. With progressive enhancement, there's no downside — only cleaner, more maintainable CSS.

FAQ

What are CSS gap decorations?
CSS gap decorations are a set of properties (gap-rule-width, gap-rule-color, gap-rule-style, gap-rule-break) that let you style the gaps between items in CSS Grid, Flexbox, and Multi-Column layouts. They replace complex border hacks and pseudo-element workarounds with native, declarative syntax.
Which browsers support CSS gap decorations?
CSS gap decorations are stable in Chrome 149+ and Edge 149+ (shipped June 2026). Firefox and Safari are developing their implementations. For production use, apply progressive enhancement — the gaps themselves work everywhere (gap property), but the decorative rules only appear in supported browsers.
How do gap decorations differ from column-rule?
column-rule only works in multi-column layouts (columns property). Gap decorations extend the same visual concept to CSS Grid and Flexbox gaps, providing gap-rule-width, gap-rule-color, gap-rule-style, and gap-rule-break properties that work across all three layout modes.
Do CSS gap decorations work with flexbox gaps?
Yes, gap decorations work with both row-gap and column-gap in flexbox. You can style the gaps between flex items just like you would in a grid layout. The properties are layout-agnostic — they apply to any gap created by the gap, row-gap, or column-gap properties.
What values does gap-rule-break accept?
gap-rule-break accepts: avoid (default — the rule tries not to break across lines), column (the rule breaks at column boundaries), page (breaks at page boundaries in paged media), and always (the rule always breaks at the specified boundary). The behavior is analogous to box-decoration-break.
Can I style row gaps and column gaps differently?
In the current specification, gap-rule-* properties apply to all gaps uniformly. For different row and column gap styling, you can use the grid-specific approach: apply background or border to the grid container combined with gap, and use gap-rule for the decorative line in the gap center.
What was the old way to style grid gaps?
Before gap decorations, developers used several hacks: (1) pseudo-elements on grid items with borders, (2) background-color on the grid container showing through gaps, (3) box-shadow on items to simulate gap lines, or (4) explicit border-right/border-bottom on all items with negative margins. All were fragile and hard to maintain.

Ready to simplify your CSS? I'm available for frontend architecture consulting and responsive design implementation. View my services or contact me directly.

Contact

Building a responsive web application?

I build production web applications using modern CSS and JavaScript. Let's discuss your project — free consultation.