Native CSS Nesting Without Sass

CSS can now nest related rules without Sass or Less. That is useful, but it does not mean every selector should disappear into five levels of indentation.

Here is a button and its hover state written as separate rules:

.button {
  background-color: blue;
}

.button:hover {
  background-color: green;
}

With nesting, the state can sit beside the base styles:

.button {
  background-color: blue;

  &:hover {
    background-color: green;
  }
}

The & represents the outer selector, so &:hover becomes .button:hover. Keeping the two rules together makes this small component easier to scan.

Media queries can stay with the component

Nesting is also useful when a responsive change belongs to one component:

.sidebar {
  width: 100%;

  @media (min-width: 48rem) {
    width: 30%;
  }
}

I prefer this for isolated components because I do not have to find a separate media-query block at the bottom of the stylesheet. If many components change at the same breakpoint, a shared media-query section may still be easier to understand.

Descendant selectors can be nested too:

.card {
  padding: 1rem;

  & h2 {
    margin-block-start: 0;
  }
}

That said, nesting does not reduce the specificity of the resulting selector. Deep nesting can produce selectors that are hard to override and even harder to read. The browser will cope; the next person editing the CSS may not.

Keep it shallow

My rule is simple: use nesting when it keeps a component’s states, descendants, or responsive changes together. Stop when the indentation starts hiding what selector the browser will actually match.

Browser support has changed since native nesting first appeared, so check the current requirements for your project before removing a build-tool fallback. Sass and Less are still reasonable if you already depend on their other features. For a new stylesheet that only needs nesting, native CSS is the simpler place to start.