I realised last night while watching a presentation by Lea Verou that I could streamline my CSS Grid layouts.
I’d been creating an overall page grid by setting body { display: grid; }
then some grid areas but realised that this only worked for direct children and didn’t help with aligning more deeply nested elements to that outer grid.
For example in the case of the main header
if I wanted its child logo, nav
and search elements to snap to the body
grid then I found myself having to duplicate the display: grid
and grid-template-areas
again on the header
.
It didn’t feel very DRY but my understanding was that while we await subgrid
, it was a necessary evil.
What I should have been using is display: contents
.
If you set your header
to display: contents
then the parent (body
) grid layout will apply to the header’s contents (logo, nav
, etc) as if the header
element (the “real” direct child of the grid) wasn’t there. This gives us good semantics without the need to redefine the grid on the header
.
Here’s a codepen to illustrate.
I was aware of the existence of display: contents
but somehow it hadn’t sunk in because I’d only read about it in the abstract. Lea Verou’s explanation made all the difference. Cheers, Lea!
Update 4/5/2019
Frustratingly, I’ve learned that although we can apply this technique, we shouldn’t… or at least not for a while.
Due to a bug in all supporting browsers the property will currently also remove the element (header
in our case) from the accessibility tree meaning that its semantics will be lost.
For reference, see:
Update 11/4/2021
Thanks to Rachel Andrew for the heads-up that this issue is now fixed in both Firefox and Chrome.
We’re now just waiting for Edge and Safari to roll out fixes before we can regard this as a safe option.