CSS nesting, six months of using it properly
It shipped, it works, and it makes stylesheets worse unless you set a rule about depth.
Native nesting removed the last common reason to reach for a preprocessor. It has also, in every codebase I have seen adopt it quickly, made the stylesheet harder to read within a month.
The failure mode is familiar to anyone who used Sass in 2015. Nesting is pleasant to write and unpleasant to read: a selector four levels deep no longer exists anywhere in the file as a searchable string, so finding what styles an element means mentally assembling it from four places.
The rule that fixed it for us is two levels, and the second level is only for states and direct modifiers — `&:hover`, `&[open]`, `& > li`. Anything that would be a third level becomes its own top-level selector with a real class name. The file gets longer and every selector in it can be found with a search.
It shipped, it works, and it makes stylesheets worse unless you set a rule about depth.
Where nesting genuinely earns its place is media queries and container queries inside the component block. Keeping the responsive behaviour next to the rule it modifies, rather than in a breakpoint section 200 lines down, is the actual win — and it does not add selector depth at all.
One practical trap: the `&` is required in more places than people expect when a nested selector starts with an element name. The specification allows bare element selectors now, but older implementations disagreed, so a bare `p { }` inside a block may silently do nothing in a browser from 2023. Write `& p` and it works everywhere.
Senior writer · Austin
Front-end developer who got tired of watching good designs die in implementation. Covers browser features and the unglamorous work of making pages fast.