This week I’ve had a couple of scenarios where I’ve needed to build a hero section with a full-width image, a large heading and a translucent sidebar overlaying the image – where the sidebar bleeds to the edge of the viewport but (crucially) the content of the sidebar aligns to what I like to call the “wrapper” grid columns – i.e. the columns of the grid where we actually want to place our content. (I have a whole other post almost written on this!)

This seems to be a fairly common occurrence with the designs that are coming my way these days, and it seems like a prime case for using pseudo-elements ( ::before or ::after ) as child items of the grid.

The markup for my grid looks like this:

<div class="grid"> <div class="grid__fig"> </div> <div class="grid__heading"> <h1>CSS Layout News</h1> </div> <div class="grid__btn"> <a href="#0">Subscribe</a> </div> <aside class="grid__sidebar"> <ul class="sidebar__list"> <li class="sidebar__item">...</li> <li class="sidebar__item">...</li> <li class="sidebar__item">...</li> </ul> </aside> </div>

The div with a class of .grid is, unsurprisingly, our parent grid container, which we need to give the property attribute display: grid .

.grid { @media (min-width: 800px) { display: grid; grid-template-columns: [start] minmax(20px, 1fr) [wrapper-start] repeat(8, var(--col)) [sidebar-start] repeat(4, var(--col)) [wrapper-end] minmax(20px, 1fr) [end]; grid-template-rows: minmax(3em, 1fr) auto minmax(auto, 1fr); grid-gap: var(--gutter); min-height: 100vh; } }

Here I’m using CSS Variables to make the code more flexible and maintainable – if you need a primer I wrote a bit about them here. I’m also naming my grid lines to make it easy to place my items.

We have three direct children of the grid container: The background image ( .grid__fig ), the heading and the sidebar, which can all be placed on the grid. The grid line wrapper-end is where I want the content of the sidebar to end, but the sidebar background needs to end at the the very edge of the viewport – the end grid line. Rather than placing the sidebar like this:

.grid__sidebar { grid-column: sidebar-start / end; }

I can place it where I want the content to go:

.grid__sidebar { grid-column: span 3 / wrapper-end; }

(Rather than adding another named grid line, which might make the grid-template-columns property start to get a bit long-winded and confusing – particularly if we have even more items we want to place – I’m just using span 3 to indicate I want it to always span 3 columns, and wrapper-end as the line where I want it to end. It’s really useful to be able to switch the syntax around this way.)

Now I just need to create a pseudo-element for the sidebar background and place it on the grid. In order to act as a grid child item it needs to be a pseudo-element of the grid container, not of a grid child:

.grid::after { content: ''; display: block; grid-column: sidebar-start / end; grid-row: 1 / 4; background-color: rgba(#f405ed, 0.5); }

The sidebar background is now in front of the sidebar content, so we just need to tweak the z-index a little:

.grid__sidebar { grid-column: span 3 / wrapper-end; ... z-index: 1; }

Here’s the end result (a homage to the magnificent CSS Layout News!):

Resources

As always, there are super smart people who have written about this stuff in-depth: