Four years ago, I wrote an article titled Minding the “gap”, where I talked about the CSS gap
property, where it applied, and how it worked with various CSS layouts.
At the time, I described how easy it was to evenly space items out in a flex, grid, or multi-column layout, by using the gap
property. But, I also said that styling the gap areas was much harder, and I shared a workaround.
However, workarounds like using extra HTML elements, pseudo-elements, or borders to draw separator lines tend to come with drawbacks, especially those that impact your layout size, interfere with assistive technologies, or pollute your markup with style-only elements.
Today, I’m writing again about layout gaps, but this time, to tell you all about a new and exciting CSS feature that’s going to change it all. What you previously had to use workarounds for, you’ll soon be able to do with just a few simple CSS properties that make it easy, yet also flexible, to display styled separators between your layout items.
There’s already a specification draft for the feature you can peruse. At the time I’m writing this, it is available in Chrome and Edge 139 behind a flag. But I believe it won’t be long before we turn that flag on. I believe other browsers are also very receptive and engaged.
Displaying decorative lines between items of a layout can make a big difference. When used well, these lines can bring more structure to your layout, and give your users more of a sense of how the different regions of a page are organized.
Introducing CSS gap decorations
If you’ve ever used a multi-column layout, such as by using the column-width
property, then you might already be familiar with gap decorations. You can draw vertical lines between the columns of a multi-column layout by using the column-rule
property:
article {
column-width: 20rem;
column-rule: 1px solid black;
}

The CSS gap decorations feature builds on this to provide a more comprehensive system that makes it easy for you to draw separator lines in other layout types.
For example, the draft specification says that the column-rule
property also works in flexbox and grid layouts:
.my-grid-container {
display: grid;
gap: 2px;
column-rule: 2px solid pink;
}

No need for extra elements or borders! The key benefit here is that the decoration happens in CSS only, where it belongs, with no impacts to your semantic markup.
The CSS gap decorations feature also introduces a new row-rule
property for drawing lines between rows:
.my-flex-container {
display: flex;
gap: 10px;
row-rule: 10px dotted limegreen;
column-rule: 5px dashed coral;
}

But that’s not all, because the above syntax also allows you to define multiple, comma-separated, line style values, and use the same repeat()
function that CSS grid already uses for row and column templates. This makes it possible to define different styles of line decorations in a single layout, and adapt to an unknown number of gaps:
.my-container {
display: grid;
gap: 2px;
row-rule:
repeat(2, 1px dashed red),
2px solid black,
repeat(auto, 1px dotted green);
}
Finally, the CSS gap decorations feature comes with additional CSS properties such as row-rule-break
, column-rule-break
, row-rule-outset
, column-rule-outset
, and gap-rule-paint-order
, which make it possible to precisely customize the way the separators are drawn, whether they overlap, or where they start and end.
And of course, all of this works across grid, flexbox, multi-column, and soon, masonry!
Browser support
Currently, the CSS gap decorations feature is only available in Chromium-based browsers.
The feature is still early in the making, and there’s time for you all to try it and to provide feedback that could help make the feature better and more adapted to your needs.
If you want to try the feature today, make sure to use Edge or Chrome, starting with version 139 (or another Chromium-based browser that matches those versions), and enable the flag by following these steps:
- In Chrome or Edge, go to
about://flags
. - In the search field, search for Enable Experimental Web Platform Features.
- Enable the flag.
- Restart the browser.
To put this all into practice, let’s walk through an example together that uses the new CSS gap decorations feature. I also have a final example you can demo.
Using CSS gap decorations
Let’s build a simple web page to learn how to use the feature. Here is what we’ll be building:
The above layout contains a header section with a title, a navigation menu with a few links, a main section with a series of short paragraphs of text and photos, and a footer.
We’ll use the following markup:
<body>
<header>
<h1>My personal site</h1>
</header>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Links</a></li>
</ul>
</nav>
<main>
<article>
<p>...</p>
</article>
<article>
<img src="cat.jpg" alt="A sleeping cat.">
</article>
<article>
<p>...</p>
</article>
<article>
<img src="tree.jpg" alt="An old olive tree trunk.">
</article>
<article>
<p>...</p>
</article>
<article>
<p>...</p>
</article>
<article>
<p>...</p>
</article>
<article>
<img src="strings.jpg" alt="Snow flakes falling in a motion blur effect.">
</article>
</main>
<footer>
<p>© 2025 Patrick Brosset</p>
</footer>
</body>
We’ll start by making the <body>
element be a grid container. This way, we can space out the <header>
, <nav>
, <main>
, and <footer>
elements apart in one go by using the gap
property:
body {
display: grid;
gap: 4rem;
margin: 2rem;
}
Let’s now use the CSS gap decorations feature to display horizontal separator lines within the gaps we just defined:
body {
display: grid;
gap: 4rem;
margin: 2rem;
row-rule: 1rem solid #efefef;
}
This gives us the following result:
We can do a bit better by making the first horizontal line look different than the other two lines, and simplify the row-rule
value by using the repeat()
syntax:
body {
display: grid;
gap: 4rem;
margin: 2rem;
row-rule:
1rem solid #efefef,
repeat(2, 2px solid #efefef);
}
With this new row-rule
property value, we’re telling the browser to draw the first horizontal separator as a 1rem
thick line, and the next two separators as 2px
thick lines, which gives the following result:
Now, let’s turn our attention to the navigation element and its list of links. We’ll use flexbox to display the links in a single row, where each link is separated from the other links by a gap and a vertical line:
nav ul {
display: flex;
flex-wrap: wrap;
gap: 2rem;
column-rule: 2px dashed #666;
}
Very similarly to how we used the row-rule
property before, we’re now using the column-rule
property to display a dashed 2px
thick separator between the links.
Our example web page now looks like this:

The last thing we need to change is the <main>
element and its paragraphs and pictures. We’ll use flexbox again and display the various children in a wrapping row of varying width items:
main {
display: flex;
flex-wrap: wrap;
gap: 4rem;
}
main > * {
flex: 1 1 200px;
}
main article:has(p) {
flex-basis: 400px;
}
In the above code snippet, we’re setting the <main>
element to be a wrapping flex container with a 4rem
gap between items and flex lines. We’re also making the items have a flex basis size of 200px
for pictures and 400px
for text, and allowing them to grow and shrink as needed. This gives us the following result:
Let’s use CSS gap decorations to bring a little more structure to our layout by drawing 2px
thick separator lines between the rows and columns of the layout:
main {
display: flex;
flex-wrap: wrap;
gap: 4rem;
row-rule: 2px solid #999;
column-rule: 2px solid #999;
}
This gives us the following result, which is very close to our expected design:

The last detail we want to change is related to the vertical lines. We don’t want them to span across the entire height of the flex lines but instead start and stop where the content starts and stops.
With CSS gap decorations, we can easily achieve this by using the column-rule-outset
property to fine-tune exactly where the decorations start and end, relative to the gap area:
main {
display: flex;
flex-wrap: wrap;
gap: 4rem;
row-rule: 2px solid #999;
column-rule: 2px solid #999;
column-rule-outset: 0;
}
The column-rule-outset
property above makes the vertical column separators span the height of each row, excluding the gap area, which is what we want:

And with that, we’re done with our example. Check out the live example, and source code.
Learn more
There’s more to the feature and I mentioned a couple more CSS properties earlier
gap-rule-paint-order
, which lets you control which of the decorations, rows or columns, appear above the other ones.row-rule-break
/column-rule-break
, which sets the behavior of the decoration lines at intersections. In particular, whether they are made of multiple segments, which start and end at intersections, or single, continuous lines.
Because the feature is new, there isn’t MDN documentation about it yet. So to learn more, check out:
- CSS Gap Decorations Module Level 1 (First Public Working Draft)
- Microsoft Edge Explainer
The Edge team has also created an interactive playground where you can use visual controls to configure gap decorations.
And, of course, the reason this is all implemented behind a flag is to elicit feedback from developers like you! If you have any feedback, questions, or bugs about this feature, I definitely encourage you to open a new ticket on the Chromium issue tracker.
The Gap Strikes Back: Now Stylable originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
from CSS-Tricks https://ift.tt/U1HulNF
via IFTTT