That’s a good little thing to know about CSS grid.
I’m sure that is obvious to many of you, but I’m writing this because it was very much not obvious to me for far too long.
Let’s take a close look.
There are two players to get into your mind here:
- The grid area, as created by the parent element with
display: grid;
- The element itself, like a
<div>
, that goes into that grid area.
For example, say we set up a mega simple grid like this:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 1rem;
}
If we put four grid items in there, here’s what it looks like when inspecting it in Firefox DevTools:
Now let’s target one of those grid items and give it a background-color
:
The grid area and the element are the same size!
There is a very specific reason for that though. It’s because the default value for justify-items
and align-items
is stretch
. The value of stretch
literally stretches the item to fill the grid area.
But there are several reasons why the element might not fill a grid area:
- On the grid parent,
justify-items
oralign-items
is some non-stretch value. - On the grid element,
align-self
orjustify-self
is some non-stretch value. - On the grid element, if height or width is constrained.
Check it:
Who cares?
I dunno it just feels useful to know that when placing an element in a grid area, that’s just the starting point for layout. It’ll fill the area by default, but it doesn’t have to. It could be smaller or bigger. It could be aligned into any of the corners or centered.
Perhaps the most interesting limitation is that you can’t target the grid area itself. If you want to take advantage of alignment, for example, you’re giving up the promise of filling the entire grid area. So you can’t apply a background and know it will cover that whole grid area anymore. If you need to take advantage of alignment and apply a covering background, you’ll need to leave it to stretch
, make the new element display: grid;
also, and use that for alignment.
The one thing I haven’t figured out how to do in grid that I could do in flexbox is to have the final item fill the remaining spaces in a row. If my top row could have two or three items, how can I make sure it’s always full width?
What about my 3×3 grid with between 7 and 9 items?
A combination of flex-wrap and align-items works for flexbox
This is why you use grid and flexbox together. Use grid when you know exactly where items go. And use flexbox when you have dynamic content (eg. listing of products).
You can always use flexbox inside a grid.
Question… is Grid the best layout mechanism for a “row” of items that wraps onto multiple rows?
Grid is best for 2-dimensional layouts, and Flexbox for 1-dimensional.
So I would argue that Flexbox would be better suited to your example, where filling up the entire row is easy.
OK. But for my responsive site, I’m gonna reflow those grid areas, so if I just stick a flex inside the grid I’m going to have to jump through hoops to reorder them.
I guess I’m just surprised there’s no min/max options on
grid-column-start
andgrid-column-end
. Feels like a regression.NB: The site design in question is fairly standard:
except there could be different numbers of items in each section based on unknowable config. While that initially sounds like a perfect place for
flex
, the nature of it is that a) some elements are always in certain places and b) the order on smaller devices could be completely different.So in essence what I’d love to do is specify an element with a
max-columns
and either agrid-column-start
or agrid-column-end
– what I’ll probably end up doing is spending a lot of time working around the edges so it behavesJymbob, you can do this in grid.
It’s also worth mentioning how a grid area relates to a grid cell: A grid area can consist of one or more grid cells. So, if you place an item into a single grid cell, then the grid area is that grid cell, and if you make the item span multiple grid cells, then the grid area represents the combined space of all those cells (including any grid gaps between the cells).
Btw, if you just need to add a background to a single grid area occupied by a non-
stretch
item, you can use one of the grid container’s pseudo-elements, and place it into the same grid area:Clever!
I guess that’s just as interesting a thing to know as this entire article itself:
You can place multiple elements in the same grid area (even aligned differently).