Sass-style nesting, zero build step — plus the trap Sass users never see coming
This nav component below is styled entirely with native nesting — inspect this page's CSS to verify. Hover and click the links.
Four placements, four meanings. The chips below use &:hover and &.active — click them. Then toggle the context flip.
& is optional for simple descendants — .card { h2 { } } works directly. You must use & for: compounds (&.active — without it, a space is inserted and the selector breaks), pseudo-classes (&:hover), and context flips (.dark &). Most 2026 style guides recommend always writing & for readability.
Native nesting wraps the parent selector in :is() — and :is() takes the specificity of its most specific item. Nest inside a comma list containing an ID, and every branch gets ID-level specificity. This demo is live — the green override below genuinely loses.
.card, #featured { h2 { } } into two separate flat rules — .card h2 keeps class specificity. Native nesting produces :is(.card, #featured) h2 — one rule at ID strength. Identical source, different cascade. Fix: never mix IDs into nested comma lists, or split the ID into its own rule.
Without &, the browser inserts a descendant space. .active nested bare means "descendant with .active" — not "self with .active".
Unlike a syntax error in a flat stylesheet (which can kill everything to the next brace), an invalid nested selector only drops its own rule — the parent and sibling rules survive. Forgiving by design.
Media queries, container queries, and feature queries can nest inside a selector — the component's responsive behavior lives with the component.
| Sass feature | Native equivalent | Verdict |
|---|---|---|
| Nesting (descendants, pseudo) | & — native | ✓ Drop Sass |
| $variables | --custom-properties | ✓ Drop Sass |
| Nested media queries | @media inside rules | ✓ Drop Sass |
| Color functions (darken…) | color-mix(), oklch from | ✓ Drop Sass |
| &__element (BEM concat) | not supported | ✗ Keep Sass |
| @each loops / maps | no equivalent | ✗ Keep Sass |
| Mixins with logic | partially (vars + if()) | ~ Depends |
In Sass, & is a string you can concatenate. In native CSS it's a selector reference. BEM codebases built on &__element must either flatten those class names or keep Sass for those files.
Keep nesting ≤3 levels. Deep nesting produces long, over-specific selectors that are hard to override — the same disease Sass codebases died of. Nest pseudo-classes, modifiers, and at-rules; don't mirror your HTML tree.
Sass and native nesting coexist fine — .scss for the two edge cases, .css for everything else, same project. Most teams find 80%+ of files migrate cleanly.
Nesting is Baseline (Chrome 120+, Firefox 117+, Safari 17.2+, 90%+ global) — fallbacks are rarely needed in 2026. For legacy targets, a PostCSS plugin flattens nesting at build time, giving you the syntax today with universal output.