CSS Nesting brings one of Sass's most-loved ergonomic features directly into the browser — but it's specified with its own semantics, not a literal copy of Sass's textual nesting, which introduces a specificity subtlety worth understanding.
1Basic Syntax And The & Operator
A selector nested directly inside another rule's block is implicitly treated as a descendant of the outer selector — .card { .title { } } behaves like .card .title { }. For compound selectors — attaching a pseudo-class or modifier class directly to the parent rather than selecting a descendant — the & operator explicitly stands in for the parent selector: .card { &:hover { } } compiles to .card:hover, not .card :hover.
This distinction (implicit descendant nesting vs explicit & compounding) is the first thing to internalize, since forgetting & for a pseudo-class is a very easy mistake that silently changes what the rule matches.
2Nesting Media And Container Queries
Beyond selectors, native nesting extends to conditional at-rules: @media and @container can be written directly inside a component's rule block, keeping every responsive variation of that component visually adjacent to its base styles in the source file, rather than requiring a reader to jump to a separate media query block elsewhere.
This is purely an authoring ergonomic — the compiled cascade behavior is identical to writing the equivalent flat, non-nested CSS. The benefit is entirely about keeping related logic co-located, which measurably reduces the cognitive overhead of maintaining a component's full responsive behavior.
3A Real Gotcha For Developers Migrating From Sass
Sass's nesting is purely a textual preprocessing step: .card { .title { } } compiles literally to .card .title { }, with identical specificity to hand-writing the flat selector. Native CSS Nesting is specified differently — nested selectors are effectively wrapped in an implicit :is(), which is what allows nesting to support complex selector lists cleanly, but which can, in specific edge cases involving mixed-specificity selector lists, produce a different effective specificity than the naive flat equivalent.
The practical takeaway isn't 'avoid nesting' — it's 'verify specificity behavior when migrating complex nested Sass patterns to native nesting', particularly around comma-separated selector lists nested together, rather than assuming a 1:1 behavioral match.
4Step-by-Step Breakdown
Sass Nesting, Now Native. For over a decade, nesting selectors inside one another was a Sass-only feature, requiring a build step just to write .card { &:hover { } }. Native CSS Nesting brings that same ergonomic directly into the browser — with one important specificity behavior that differs subtly from what Sass developers expect.
Basic Nesting And The & Operator. Inside a rule's declaration block, you can nest another selector directly, and it's implicitly compiled as a descendant selector. The & symbol explicitly refers to the parent selector, essential for compound selectors like pseudo-classes or modifier classes that shouldn't be treated as descendants.
The & Operator. Why is &:hover needed instead of just :hover when nesting inside .card { }?
- →Because :hover alone inside a nested block is a syntax error
- →Because & explicitly attaches :hover to .card itself, forming a compound selector, rather than treating it as a descendant
- →There's no real difference between the two forms
Nesting Media And Container Queries. Nesting isn't limited to selectors — @media and @container at-rules can be nested directly inside a rule too, keeping a component's responsive behavior visually co-located with its base styles instead of split into a separate media query block elsewhere in the file.
Nesting At-Rules. What's the practical benefit of nesting @media directly inside a component's rule instead of writing it separately?
- →It makes the CSS render meaningfully faster
- →It keeps a component's responsive variations visually co-located with its base styles
- →Nesting @media is required; it can no longer be written standalone
The Specificity Gotcha For Sass Developers. Native CSS nesting wraps implicit nested selectors in :is() internally, which means a nested selector's specificity is calculated differently than the equivalent hand-written flat selector would be — surprising developers used to Sass's purely textual nesting, which had no such effect.
Nesting's Specificity Behavior. Why can native CSS nesting produce a different specificity result than the visually equivalent flat selector?
- →It's a browser bug that will eventually be fixed
- →The spec defines nested selectors as implicitly wrapped in :is(), which affects specificity calculation in edge cases
- →There's actually never any specificity difference
Native Nesting Fluency. You can now nest selectors and at-rules natively, use the & operator correctly for compound selectors, and you know about the implicit :is() wrapping that can make native nesting's specificity subtly differ from what Sass developers expect.
Nest A Selector With Native CSS. Native CSS nesting lets you write a child selector directly inside its parent rule using &.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Co-located Nested Focus Styles Are Less Likely To Be Forgotten During Refactors
Writing &:focus-visible directly inside a component's own rule block makes it far more visible during a refactor than a separate, disconnected focus rule defined elsewhere in the stylesheet, reducing the chance it's accidentally dropped.
2Nested @media Blocks Should Still Be Checked For prefers-reduced-motion And prefers-contrast
Co-locating responsive breakpoints doesn't automatically mean user-preference media features are considered — explicitly nest @media (prefers-reduced-motion: reduce) alongside size-based breakpoints when a component includes motion.
SEO Implications
- 1
Nesting Doesn't Change Compiled Output Size Meaningfully By Itself
Native nesting compiles to the equivalent flat CSS at the engine level, so its SEO impact is neutral to positive — mainly through the maintainability gains that make it easier to keep stylesheets lean over time.
- 2
Removing A Sass Build Step For Nesting Can Simplify And Speed Up The Build Pipeline
Projects that adopted Sass primarily for nesting ergonomics may be able to remove that build dependency, which can shave measurable time off CI/CD pipelines feeding into deploy and, indirectly, iteration speed on SEO-relevant content.
Best Practices
Always Use & Explicitly When Attaching A Pseudo-Class Or Modifier To The Parent
Omitting & for something like :hover silently changes the selector's meaning from a compound selector to a descendant selector, which is a very easy and hard-to-spot mistake.
Test Complex Nested Selector Lists When Migrating Existing Sass Code To Native Nesting
Given the implicit :is() semantics, don't assume 1:1 specificity parity with a Sass-compiled equivalent — verify visually or with a specificity calculator for non-trivial nested selector lists.
Frequent Bugs
A nested pseudo-class rule matches descendants instead of the parent element itself.
The & operator was omitted. `:hover { }` nested inside .card is a descendant selector; `&:hover { }` is the intended compound selector.
A specificity conflict appears after migrating nested Sass code to native CSS nesting, with no visible selector change.
Native nesting's implicit :is() wrapping can alter specificity for selector lists in ways Sass's textual nesting didn't — recalculate specificity for the migrated rule rather than assuming it's unchanged.
Real-World Examples
A Fully Native-Nested Component
A card component with its hover state, a nested element, and a responsive breakpoint all defined natively within a single nested rule block, no Sass required.
.card {
padding: 16px;
& .card__title { font-weight: 700; }
&:hover { box-shadow: 0 4px 12px rgba(0,0,0,.1); }
@media (min-width: 768px) {
display: grid;
}
}