CSS Nesting Table

PieceSyntaxField note
nested type selector.card { h2 { ... } }2023 baseline - Sass-style nesting, native, no build step
nested class/id.card { .title { ... } }Starts with identifier - no & needed for classes
nested element needs &.card { & h2 { ... } }Element selectors MUST use & - the one hard rule
& = the parent&:hover, &.activeWhere the parent goes in the compound selector
@media nested.card { @media (...) { ... } }Conditions nest inside rules now - media with its styles
specificity unchangedSame as flat equivalentNesting is SYNTAX sugar - specificity math does not change
beware over-nesting3 levels max, mostlyDeep nesting rebuilds the Sass specificity mountain in place
direct child >.card { & > p }Combinators ride on & - descendant is the default
Reference: the MDN CSS nesting reference. Native nesting (2023 baseline) brings Sass's colocation to real CSS: styles live beside their component, media conditions nest inside rules, and no build step preprocesses anything. The one hard rule: element selectors inside a nest need & (h2 alone is invalid; & h2 works), while classes can start bare. Bottom line: nesting changes SYNTAX, not SPECIFICITY - a nested h2 has exactly the weight it would flat, so the danger is not the parser but the habit: three levels deep rebuilds the specificity mountain Sass taught us to fear. Keep nests shallow and the cascade predictable. Related tools: cascade layers table (the architecture that survives nesting), :has table (parent selection as nesting's sibling feature), and custom properties table (tokens that pass through nests unchanged).

Native CSS nesting (2023 baseline) brings Sass's colocation to real CSS: styles live beside their component, media conditions nest inside rules, and no build step preprocesses anything - the browser parses it directly.

Bottom line: nesting changes SYNTAX, not SPECIFICITY. A nested h2 weighs exactly what it would written flat - the compiled meaning is identical. The danger is not the parser but the habit: five levels deep rebuilds the specificity mountain that made Sass stylesheets unrefactorable.

The honest part: the one hard rule trips everyone once - element selectors inside a nest REQUIRE the ampersand (.card { h2 { } } is invalid; .card { & h2 { } } works), while class selectors may start bare (.card { .title { } } is fine). The rule exists because bare elements are ambiguous with properties.

How to use

  1. Nest your component: .card { padding: 1rem; .title { font-weight: 700; } &:hover { box-shadow: ...; } } - one block, the whole component, zero prefixes.
  2. Move media INTO the rule: .sidebar { display: block; @media (min-width: 700px) { display: none; } } - the condition travels with the styles it governs.
  3. Cap the depth: component root, part, state - three levels. If you need four, the selector is doing architecture that layers or custom properties should do.

Frequently asked questions

Why do element selectors need the ampersand but classes do not?

Parser ambiguity. Inside a nested rule, the browser must distinguish a DECLARATION (color: red) from a NESTED RULE - identifiers that start with a dot, hash or bracket are unmistakably selectors, so .title needs no marker. A bare h2, however, would parse as a custom property named h2 followed by junk - custom property names legally contain hyphens and look exactly like that. The & prefix makes the selector intent explicit. So the mnemonic: things that cannot be properties (start with . or # or [) nest bare; things that could be properties (elements) take the &.

Does nesting change specificity or the cascade?

No - and this is the property that makes it adoptable in old codebases. Native nesting is defined as SYNTACTIC SUGAR for the equivalent flat selectors: .card { & h2 {} } compiles to .card h2 {} with identical specificity, identical cascade position, identical everything. Unlike Sass, which sometimes emitted selectors differently than authors expected, the native spec guarantees the flat translation. The practical warning is therefore not mechanical but human: convenient nesting invites deep, high-specificity selectors that fight the cascade later - the syntax is new, the architecture discipline is not.

How do nested media queries change stylesheet organization?

They colocate conditions with consequences: the sidebar's mobile and desktop behavior live in one block, instead of a 300-line @media section at the file's bottom that restyles every component by exception. This is the single biggest maintainability win of nesting - responsive changes become LOCAL edits. The complement to know: container queries (from the container query table) go further by keying conditions on the CONTAINER's size rather than the viewport - nested @media handles viewport-responsive components; @container handles placement-responsive ones.

When should I migrate an existing Sass codebase to native nesting?

Incrementally, and only when the build allows it. Native nesting covers Sass's most-used feature but not its ecosystem: mixins, functions, loops and variables (now CSS custom properties) have no native equivalent. The working migration: new components write native nesting directly, Sass files convert opportunistically when touched, and the preprocessor eventually only handles what it still uniquely does - then leaves. The ordering trap: do not convert a file while BOTH systems compile it (double selectors); convert whole files, and verify the compiled output is selector-identical before deleting the Sass source.

Related tools