I like being able to keep a component's states beside its ordinary styles. The difficulty is knowing when that convenience starts to hide what the browser actually has to match.
Native CSS nesting gives us some of that organisation without requiring Sass to interpret the stylesheet. I still want the result to be easy to follow when I come back to a WordPress theme months later. My rule is to nest around a component's behaviour, rather than reproduce the whole page inside the CSS.
In this tutorial: What we are building; Before you start; 1. Keep the component boundary visible; 2. Avoid nesting the page into the stylesheet; 3. Watch specificity when grouping selectors; Check the behaviour.
What we are building
A small article card with a heading, a link and a clear keyboard focus state. The example uses native CSS nesting, not SCSS. It belongs in a stylesheet delivered to browsers that support the syntax, or in a build that converts nesting for the browsers you support.
Before you start
Keep a flat version of the component working first. That gives you something to compare against when checking whether the nested selectors still match the intended elements.
Modern support does not remove the need to agree browser requirements. If older browsers matter, I would compile the syntax during the build. Nesting does not provide its own fallback, and a browser that cannot understand a nested rule will not turn it into an equivalent flat selector.
1. Keep the component boundary visible
.article-card {
padding-block: 1.5rem;
border-block-end: 1px solid currentColor;
& > h2 {
margin-block: 0 0.5rem;
}
& a {
text-underline-offset: 0.2em;
}
&:focus-within {
outline: 2px solid currentColor;
outline-offset: 4px;
}
}
The explicit ampersand means the parent selector. The heading rule becomes .article-card > h2; the link rule becomes .article-card a. That direct relationship is easy to check in the browser's inspector.
I have kept the card's focus state at the same nesting depth as its children. There is no benefit in wrapping it inside a sequence of layout selectors first.
2. Avoid nesting the page into the stylesheet
If I find myself writing selectors through the page, section, row, column, card and heading, I stop and ask which element actually owns the styling. A small class on the component is usually clearer than a description of where it happens to live today.
That matters in a CMS. A client can move a section, repeat a pattern or place the same component beside different content. Styling tied to a long ancestor chain makes those ordinary editorial changes unexpectedly fragile.
Native nesting also is not a replacement for every Sass feature. In particular, appending a class suffix with &__title is a Sass convention, not a native way to construct a new class name. I would write .article-card__title explicitly where that is the selector I mean.
3. Watch specificity when grouping selectors
Nested selector lists have specificity behaviour related to :is(). Mixing a high-specificity selector, such as an ID, with an ordinary class can make the nested result more forceful than a quick glance suggests.
I prefer separate component rules to clever grouping when that grouping would make an override hard to explain. Nesting saves some repetition; it should not make me reach for !important elsewhere to undo an accidental increase in specificity.
Check the behaviour
Compare the flat and nested versions at a narrow and wide viewport. Tab to the card link and check that its outline is visible rather than clipped. Move the card into a different section and confirm its appearance does not depend on the old ancestors.
Finally, inspect the built file that a visitor receives. If the build is meant to compile nesting, check that it actually has. The source looking tidy does not tell me whether the delivered stylesheet meets the browser requirements.
I am happy to use nesting when it shortens the journey from a component to its states. Once it starts concealing that journey, a few repeated selectors are a reasonable price for clarity.
References
MDN's guide to CSS nesting explains the syntax and its differences from preprocessors. For stylesheet organisation, see my notes on Sass mixins.