I was recently asked is it possible to select every element in the last row of a grid containing an arbitrary number of items using CSS selectors?
Not wanting to shy away from a challenge, I started hacking and found a solution which I’ve written up along with a few other techniques for targeting elements in the first or last row of a grid.
Throughout this post I’ll be using the terms “balanced grid” and “unbalanced grid”. So we’re clear, a balanced grid has content in every grid cell and an unbalanced grid doesn’t have enough content to fill every cell, resulting in whitespace in the last row.
For this post I’ll be working with the follow test markup. These techniques are very flexible and can be adapted to work with any markup that uses sibling elements to create a grid.
Styling the first row of a grid
Targeting elements in the first row of a grid is relatively simple. It doesn’t matter if the grid is balanced or unbalanced, the same solution applies to both cases. We need a selector that will only target the first x elements, where x is the number of columns in the grid. We can do that with the :nth-child
pseudo-class:
For a 3 column grid:
For a 5 column grid:
For a 12 column grid:
Styling the last row of a balanced grid
Targeting elements in the last row of a grid is simple if the grid is balanced. The same principles used to target the first row are used here except we’ll use the :nth-last-child
pseudo-class to target the last x elements in the grid. Again, we’re substituting x with number of columns in the grid.
Last row of a balanced 3 column grid:
Last row of a balanced 5 column grid:
Last row of a balanced 12 column grid:
Last row of a balanced or unbalanced grid
Styling elements in the last row is a little more tricky if the grid is unbalanced. Unlike the selector used for a balanced grid, we can’t just target the last xth elements and style them. What if the grid has 5 columns with only 3 elements in the last row? – we would target the last 2 elements in the previous row too.
To style the last row of a grid we’re going to use the following rule, again, substituting x with number of columns in the grid.
The :nth-child(Xn+1)
pseudo-class will target every xth element in the grid, which will be the first item in each row. The :nth-last-child(-n+X)
pseudo-class will target the last x elements in the grid. Combining these pseudo-classes will only target elements that match both, which in our case is the first element in the last row of the grid.
To select all elements in the last row we add a general sibling combinator ~
to the previous selector so it targets everything after the first element in the last row.
Last row of a balanced or unbalanced 3 column grid:
Last row of a balanced or unbalanced 5 column grid:
Last row of a balanced or unbalanced 12 column grid:
If the grid will always have two or more rows, or if you want to completely ignore single row grids, a simpler selector can be used. This selector will fail to match the first item in a grid with a single row. To use it, substitute x with the number of columns in the grid and y with the number of columns in the grid +1:
Last row of a balanced or unbalanced 3 column grid with more than one row:
Last row of a balanced or unbalanced 5 column grid with more than one row:
Last row of a balanced or unbalanced 12 column grid with more than one row:
The end
I hope you found this useful.
Why don't you use the
:last-child
? Now i can't see if your list items go from top to bottom or left to right but this makes it alot easier.Also why do you use a list for a grid? I can't figure out why.
:last-child
would only select the very last element, the purpose of this is to select all elements in the last row of a grid.I'm using a
<ul>
list because this solution was originally developed for displaying a grid of products and portfolio items.So if im correct your using one
ul
and repeat theli
. Well that makes things alot more clear.WOW - How did you manage to sort that one out. Well done and thanks for letting us see it.
Regards George