Creating a ruled CSS grid layout
When working with CSS Grid, adding internal borders between items — like the clean, ruled lines of a table or spreadsheet — isn’t as straightforward as simply applying a border to each grid item. There’s no native way to do this, though I’ve seen a few different approaches. I still wanted to write this post because I think the following method is the most straightforward. That said, each method likely has its pros and cons (which are outside the scope of this post). There’s a short video at the end that highlights the steps.
Let's start with some code examples and a graphic to highlight the issue we face. If you simply add a border to each item, your ruled grid will be off.
<div class="ruled-grid">
<div class="ruled-grid__item">Item 1</div>
<div class="ruled-grid__item">Item 2</div>
<div class="ruled-grid__item">Item 3</div>
<div class="ruled-grid__item">Item 4</div>
<div class="ruled-grid__item">Item 5</div>
</div>
.ruled-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.ruled-grid__item {
padding: 2rem;
border: 2px solid #000;
}

Where the borders meet, you end up with double border thickness, making the whole thing look wrong.
To fix the issue we have in the example above you can apply both a border
and an outline
– of the same size and color. This would be a good use case for a CSS variable. The visual border will be the combined width of the border + outline
– in this case 4px
.
.ruled-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.ruled-grid__item {
padding: 2rem;
border: 2px solid #000;
outline: 2px solid #000;
}

This looks pretty good. We have kind of achieved what we want.
But what if we make the border a bit thicker? Let's bump the border
and outline
up to 12px
to highlight one more thing.
.ruled-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.ruled-grid__item {
padding: 2rem;
border: 12px solid #000;
outline: 12px solid #000;
}
Look at the left edge of the grid container and the heading above in the following image. The left edge and the beginning of the heading should align. What is happening is that the border of the grid extends out of the parent container (since outlines don't take up space). This is barely noticeable and not really an issue unless you have quite thick borders.

Now the border lines extend outside of the container in a noticeable way.
But we can fix that by adding the same padding to the grid parent.
.ruled-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
padding: 12px;
}
.ruled-grid__item {
padding: 2rem;
border: 12px solid #000;
outline: 12px solid #000;
}

After adding the correct padding to the grid parent, everything should align nicely.