If you inspect the current version of my site, you’ll notice a much flatter structure, and that’s thanks to CSS Subgrid.
I leaned on CSS Grid for my layout when I first started building this site, creating a reusable grid with named columns for things like full-bleed sections, pop-out content, and the main reading column. The goal was to keep all layout decisions centralised while maintaining good readability and flexibility across the site. It made building pages fast and consistent, and was inspired by articles like Layout breakouts with CSS Grid - Ryan Mulligan. I actually used this layout in my styles because the solution was so good.
Before using Grid on my own site, I’d mostly used Grid in smaller scenarios where Flexbox started to fight back. But while building a reusable site layout, I still found myself repeating structural code. Sure, I made my layouts reusable, classes like .wrapper for my grid container and .popout or .fullone – best class name I've ever written btw – for aligning to specific columns in my grid. But that still meant on my homepage .wrapper was repeated numerous times... 4 to be exact. Not earth shattering I know, it just felt repetitive for no good reason.
I recall grumbling "Why cant I get access to my grid everywhere, why just the direct children". This was in 2022 when I created this site and Subgrid was only available in Firefox. Alas I moved on, my life continued on from there with no issues. My site functioned perfectly and no one rolled over in their grave because of my repeated use of .wrapper.
So I rebuilt it with Subgrid
Recently I had an itch to do more to my site, I had seen Subgrid being mentioned in a few newsletters and it was baseline as well, so I decided to take a look to understand the problems CSS Subgrid solved.
From my initial learning and reading about Subgrid a thought germinated, which was that I could define my Grid as the top level parent of my markup and leverage Subgrid elsewhere to align to the columns I want. The world would finally be saved from my overuse of .wrapper divs and I could then rest.
So thats what I did. Now I have a single div which acts as my grid container, its right at the top of DOM. Ive removed the .wrapper divs for each section that used my old Grid styles and now I opt into Subgrid instead.
I started with just adding bunch of selectors where I need inherit Subgrid, they were .header, .footer, .main. This allows me to have full-bleed panels for those parts and then all their children fall into the main reading column.
.header,
.footer,
.main {
display: grid;
grid-column: full;
grid-template-columns: subgrid;
:where(&)>* {
grid-column: content;
}
}
This chunk of css covers 90% of my layout needs, but I do have some sections of content where for fancy design purposes things should popout of the main reading column. This popout content appears on my blog page as the hero image and homepage for the intro content.
I originally thought I could just drop a grid-column: popout in a utility class and call it a day. But I was wrong, I did have to do a little more then what I thought. It wasnt much and it was just my understanding of Grid and Subgrid at that moment. So lets talk through the solution focusing on the homepage first.
Excluding header and footer HTML this is the overall structure.
<main class="main">
<section class="section">
<div class="intro">...</div>
</section>
<section class="section">
...
</section>
</main>
Subgrid gets applied to the .main to make it full-bleed - .main has a background colour for when my content slides over the header on scroll. The recent article section has a different background colour from the .main which needs to also be full-bleed. Finally my intro content needs to popout of the main reading column... cause of super awesome design reasons.
As mentioned just dropping a utility class of grid-column: popout on specific sections wasn't quite right. To achieve what I needed, the .section container also needed to participate in the same grid. The tracks were already defined on .main, but .section needed to inherit them as well. What I hadn’t fully understood initially about Subgrid was that every nested grid container can opt back into the same track system. Once .section also used Subgrid, deeply nested elements could still align to — or intentionally span beyond — the original layout columns. So I added .section to the list of selectors using Subgrid. This meant I got the full-bleed for the background of the recent article section for free. Then all I had to do was drop grid-column: popout as a property inside the .intro class.
The blog post page is much more sane compared to my homepage, except for my need to popout the hero image. On that page, it was the same sort of solution heres the overall structure.
<main class="main">
<article class="article">
<header class="article-header">...</header>
<div class="article__hero">
<img src="..." alt="">
</div>
</article>
</main>
The blog layout followed the same pattern — .article became a Subgrid container and .article__hero handled the popout styling. Leaving me with this block of css.
.header,
.footer,
.main,
.section,
.article {
display: grid;
grid-column: full;
grid-template-columns: subgrid;
:where(&)>* {
grid-column: content;
}
}
.article__hero,
.intro {
grid-column: popout;
}
Did all of this make a huge difference? Yes. I now have a single place where my grid is defined at the top level. With Subgrid, nested sections can align to that same structure without needing additional wrapper elements. The result is less HTML and a cleaner layout overall.
Before Subgrid
<main>
<div class="wrapper homepage">
<article class="content popout">
<div class="intro">...</div>
</article>
</div>
<div class="wrapper homepage alt-bg">
<div class="content">
...
</div>
</div>
</main>
After Subgrid
<main class="main">
<section class="section">
<div class="intro">...</div>
</section>
<section class="section">
...
</section>
</main>
At the time of publishing could my classes be better? Maybe. I could have more utility classes but for the moment its working for me, its a simple site, not a sprawling commercial website maintained by distributed teams in 3 different timezones. So I'm okay with it.
I do plan on doing more, I have some more design changes I want to make to improve my sites layout and try to get away from this simple single column design for absolutely everything and push Subgrid a bit further.
If you havent played with Subgrid yet, I recommend it. You're going to find instances like I did where it will make your feel more efficient. My sites design is pretty basic and Subgrid can do soooo much more, but this modern CSS world we live in is amazing. Especially because when I started tables was where it was at for layouts.