Comment by moron4hire
4 days ago
Yes, for that specific example it works. But in general, this essentially deletes the UL from the layout entirely. It won't be stylable[0] and it won't dispatch UI events that occur on it specifically.
One example of a reason you might want such an element to still participate in layout is to use that element as an area highlighter. Or you might make it a scrollable section; subgrid makes sticky-header tables rather trivial to implement now.
[0] Well, I can't remember right now if it's unstylable or if its height just ends up zero, but either way, it might not be what you expect.
One subtle thing worth adding is that display: contents also changes how accessibility trees are constructed. The element is removed from the visual layout and from the accessibility tree in many browsers, so semantics like list grouping, landmarks, or ARIA roles can disappear unless you re-introduce them manually.
That’s why subgrid ends up filling a different niche: you preserve the DOM structure, preserve accessibility semantics, and still let the children participate in the parent’s track sizing. It costs more than contents, but it avoids a lot of the accidental side-effects that show up once you start mixing layout, semantics, and interactivity.
Yeah this is a good callout. My understanding is that display: contents is not meant to impact the accessibility tree but there is a long and ongoing history of browser bugs that make me not want to use it for elements that have an accessible role
From my testing, as far as I've been able to tell it no longer has any impact on accessibility. The element itself does not appear in the tree, this makes sense display:contents is non-interactive. But all of the children correctly appear in the accessibility tree as if they did not have that shared parent element. But I am by no means an expert at operating screen readers, do you know of any specific issues with it?
1 reply →
Yeah, though I find in practice I use `display: contents` far more than I do subgrid. Contents effectively deletes the node for layout purposes, but it still participates in the CSS cascade so you can use it in selectors, even `:hover` works when a child gets hovered, or use it as the origin for inheritable properties.