Home / Articles / Modern CSS /

New featureno-js

CSS nesting syntax

Native nesting is here — the number one reason to use Sass is gone.

Why nesting needed to be native

Nesting was the single most popular feature of CSS preprocessors. It reduces repetition, groups related rules visually, and makes component styles scannable. But preprocessor nesting requires a build step, adds tooling complexity, and outputs flat CSS that doesn't match what you wrote. Native CSS nesting removes all of that — the browser understands nested selectors directly.

The syntax

Nest selectors inside a parent rule block. The & character refers to the parent selector:

.card {
  background: oklch(1 0 0);
  border: 1px solid oklch(0 0 0 / 0.07);
  border-radius: 1rem;

  /* Nested element selector */
  h2 {
    font-size: 1rem;
    color: oklch(0.18 0.025 260);
  }

  /* Nested pseudo-class with & */
  &:hover {
    box-shadow: 0 4px 16px oklch(0 0 0 / 0.1);
  }

  /* Nested modifier */
  &.card--featured {
    border-color: oklch(0.52 0.22 265);
  }

  /* Nested media query */
  @media (max-width: 32rem) {
    padding: 1rem;
  }
}

The & is optional for element selectors and pseudo-classes in 2026 — the browser infers it. But it's required when you need the parent as part of a compound selector like &.card--featured.

Nesting @rules

You can nest @media, @container, @supports, and @layer inside a rule block. This keeps responsive and conditional logic next to the properties they affect:

.sidebar {
  width: 20rem;

  @container (max-width: 40rem) {
    width: 100%;
  }

  @media (prefers-color-scheme: dark) {
    background: oklch(0.19 0.02 260);
  }
}

Specificity

Nested selectors compile to the equivalent flat selector for specificity calculation. .card h2 nested inside .card has the same specificity as .card h2 written flat. There are no specificity surprises — nesting is purely syntactic sugar.

One subtlety: the & selector uses :is() internally for grouping. If you nest inside a selector list, each item in the list is wrapped in :is(), which takes the highest specificity of its arguments. This rarely matters in practice, but it's worth knowing.

Migrating from Sass

The native syntax is close to Sass nesting, with one key difference: Sass lets you concatenate selectors with & (e.g., &__title for BEM). Native CSS does not — & must be a complete selector. If you use BEM concatenation, you'll need to write those as flat selectors or switch to data-* attribute patterns.

Start migrating by removing your Sass nesting first, then re-adding it with native syntax. Keep nesting shallow — two or three levels maximum for readability.

Browser support

Native CSS nesting is supported in Chrome 120+, Safari 17.2+, and Firefox 117+. In 2026, it's Baseline Widely Available. You can start using it today in any project that doesn't need to support very old browsers.