> All in One 586: July 2025

Ads

Tuesday, July 1, 2025

The Gap Strikes Back: Now Stylable

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;
}
Two 1-pixel solid black vertical lines separate a row of three text blocks.

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;
}
A 2-pixel solid light pink vertical line separates two side-by-side text blocks.

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;
}
Six items flowing horizontally in two rows in a flex container, separated by 5-pixel dashed coral-colored vertical lines and a single 10-pixel dotted lime-green line between the two rows.

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);
}
Seven text blocks stacked vertically separated by horizontal lines that are styled differently.

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:

  1. In Chrome or Edge, go to about://flags.
  2. In the search field, search for Enable Experimental Web Platform Features.
  3. Enable the flag.
  4. 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:

Webpage titled My Personal Site in the header above a horizontal navigation and a staggered, masonry-like layout of text and images with thin lines between them. The design is in black and white.

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:

The basic layout for the webpage. The title is the same but the navigation and layout are both vertically stacked. There are no lines between items in the layout.

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:

The webpage is largely the same, but the border between the site title and the navigation is much thicker.

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 webpage is still largely the same, but now the navigation is horizontal and there is a light dashed line between the links.

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:

The webpage layout has been established but there are no lines between items.

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:

Thin light lines have been added between the layout of text and images, creating a masonry-like layout. The lines extend all the way across each item like enclosed boxes.

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:

Spacing has been added between the layout items so that the lines between them are no longer connected, creating an elegant layout.

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:

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

The Gap Strikes Back: Now Stylable

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