IAnswerable

Native CSS Nesting Is Here

28 Oct 2026

Native CSS nesting works in every current browser now. Drop Sass if nesting is the only reason you have it in your build.

The basic syntax

.card {
  padding: 1rem;
  border: 1px solid #ddd;

  & h2 {
    margin-top: 0;
  }

  &:hover {
    border-color: #999;
  }

  & .card-footer {
    margin-top: 1rem;
  }
}

The & refers to the parent selector, same as Sass. Unlike Sass, you can actually omit it in some cases — but don’t, and here’s why.

The syntax trap: nesting a bare type selector

This looks reasonable and does something you don’t want:

.card {
  color: #222;
  p {
    margin: 0;
  }
}

That p rule is parsed as .card p, which is what you’d expect and actually fine here. The trap is when the nested selector starts with an identifier that CSS could also parse as a declaration. Nesting a selector that starts with something ambiguous, like a custom property lookalike or a selector CSS can’t disambiguate from a property, causes a parse error and the browser drops the whole block silently. In practice the safe habit is: always start nested selectors with & when there’s any doubt, and always start them with & when the selector is a bare type selector combined with something after it.

The rule that actually bites people: a nested rule whose selector doesn’t start with &, a type selector, *, or a few other allowed starts will fail to parse. The fix that sidesteps all the edge cases:

.card {
  & p {
    margin: 0;
  }
}

Prefix every nested selector with &. It costs three characters and removes an entire class of silent parse failures. Don’t rely on the bare-selector shorthand even where it happens to work — it’s inconsistent across selector types and it’s not worth memorizing the exceptions.

Nesting media queries and other at-rules

This is the part that used to require a preprocessor and now doesn’t:

.sidebar {
  width: 300px;

  @media (width < 768px) {
    width: 100%;
  }

  @container (min-width: 400px) {
    padding: 2rem;
  }
}

No & needed inside @media — the at-rule just wraps the existing selector context.

Nesting and specificity

Native nesting doesn’t lower specificity the way people sometimes assume. .card & p compiles to the same specificity as if you’d written .card p by hand — nesting is sugar over the flat selector, not a new cascade mechanism. If you’re fighting a specificity war, nesting alone won’t fix it; see cascade layers for that.

What you still lose without Sass

Variables — but CSS custom properties cover that. Mixins and functions — CSS still doesn’t have real functions beyond calc() and the new clamp()/min()/max() trio. If your build actually uses Sass @mixin, @each over a list, or @function, keep Sass. If it’s nesting and variables, native CSS replaces it and you delete a dependency and a build step.

Verdict

Migrate incrementally — native nesting and Sass nesting can coexist in the same file during a transition since the syntax is compatible. Prefix every nested selector with &, always. That one habit avoids the only real gotcha here.