Dave Rupert with some modern CSS magic that tackles one of those classic conundrums: what happens when the CSS for component is unable to handle the content we throw at it?
The specific situation is when a layout grid expects an even number of items, but is supplied with an odd number instead. We’re left with a “dangling” element at the end that throws off the layout. Sounds like what’s needed is some Defensive CSS and Dave accomplishes it.
He reaches for :has()
to write a nifty selector that sniffs out the last item in a grid that contains an odd number of items:
.items:has(.item:last-of-type:nth-of-type(odd)) .item:first-of-type { }
Breaking that down:
- We have a parent container of
.items
. - If the container
:has()
an.item
child that is the last of its type, - …and that
.item
happens to be an odd-numbered instance, - …then select the first
.item
element of that type and style it!
In this case, that last .item
can be set to go full-width to prevent holes in the layout.
If… then… CSS has conditional logic powers! We’re only talking about support for Safari TP and Edge/Chrome Canary at the moment, but that’s pretty awesome.
As chance has it, Temani Afif recently shared tricks he learned while experimenting with implicit grids. By taking advantage of CSS Grid’s auto-placement algorithm, we don’t even have to explicitly declare a fixed number of columns and rows for a grid — CSS will create them for us if they’re needed!
No, Temani’s techniques aren’t alternative solutions to Dave’s “dangler” dilemma. But combining Temani’s approach to repeatable grid layout patterns with Dave’s defensive CSS use of :has()
, we get a pretty powerful and complex-looking grid that’s lightweight and capable of handling any number of items while maintaining a balanced, repeatable pattern.
We can do it with using :has() as well
the selector
.grid div:last-of-type:nth-of-type(odd)
can do the jobYou don’t have to use Safari Technology Preview (TP), Safari has supported
:has()
since 15.4 in March. That means it works in all browsers on most iPhones & iPads (over 80% of devices are running iOS 15.4 or newer).For this use, everything works in browsers that don’t support
:has()
the layout is merely not quite as nice.