Front-end education for the real world. Since 2018.





A handy use of subgrid to enhance a simple layout

Andy Bell

Topic: CSS

We’ve got this pattern on the Set Studio website. It’s three summaries with headings that render in a three column grid which as the viewport reduces in space, automatically stack.

The “Why work with us” section on the Set Studio site contains a three-column layout explaining the agency’s value proposition. The three bold, black subheadings read: “Invest smart and strategically,” “Adapt or get left behind,” and “Trust us to deliver the goods.” Each is followed by a brief paragraph highlighting the agency’s efficient process, competitive positioning, and reliable delivery.

The three column grid part is pretty straightforward, we’re first using this little layout composition.

Code language
css

.grid {
  display: grid;
  grid-template-columns: repeat(
    var(--grid-placement, auto-fill),
    minmax(var(--grid-min-item-size, 16rem), 1fr)
  );
  gap: var(--gutter, var(--space-l));
}

Then we’re hinting the browser to make it a three column grid, where it can, using a CUBE CSS exception.

Code language
css

.grid[data-layout='thirds'] {
  --grid-placement: auto-fit;
  --grid-min-item-size: clamp(16rem, 33%, 20rem);
}

If we just leave the CSS like that (with a little help from our base styles), its looks ok, but the differing heading lengths at narrower viewports creates an awkward reading line. Ideally, each of those summaries will be on a consistent, horizontal reading line.

Demo

We’re using CSS grid already for our layout, so to achieve that consistent horizontal reading line, we can leverage subgrid.

Code language
css

.grid > div {
  display: grid;
  grid-template-rows: subgrid;
  gap: 0;
  grid-row: span 2;
}

Each direct child of our outer grid layout is a <div> element so we directly select those with the > combinator.

Next, we apply display: grid and set a value of subgrid to our grid-template-rows property, instructing this element to inherit the row structure from the parent .grid. For subgrid to work, we have to make it a grid element first.

There’s no row structure defined on our outer .grid layout — it only defines columns — and we’re instructing this child element to inherit the row structure, so we need to define what that row structure looks like with grid-row: span 2. In human language, that is “take up two consecutive rows in the parent grid, wherever you get placed”.

Now, you might be thinking “we don’t need subgrid to do that” and you’re right, we don’t need it for a row structure, but what we do need is all of our headings and all of our summaries to participate in the same layout structure as each other to achieve our goal of everything being nice and level.

Let me show you what this looks like without our row structure definition.

Demo

Not great, right? With the row definition though, we’re looking good here.

Demo

The last part of this inner layout to touch on is that we need to remove gap because there’s a bit too much space here. This is because the parent grid’s gap is inherited via subgrid. Setting in inner layout’s gap to 0 levels that out for us.

That’s the layout sorted, so let’s add a nice bit of decoration with a border on our summary:

Code language
css

.grid p {
  border-block-start: 1px solid;
  padding-block-start: var(--space-m);
}

We’re only defining the border-width and border-style (via the border-block-start shorthand) because we want the colour to be inherited. Try setting the color property in your dev tools to see that in action.

Lastly, we’re setting a bit of space above our border with padding-block-start to keep things nice and neat, visually. With that, we are done.

Demo

Wrapping uppermalink

I’ll be honest, I don’t often find many uses for subgrid in the work I do, but it’s really handy when I need this level of visual control!

This sort of pattern would have required all sorts of calculations and nasty, specific code in years gone by, but subgrid has removed the need for all of that now.

Enjoyed this article? You can support us by leaving a tip via Open Collective


Newsletter