CSS Nesting

CSS nesting allows related style rules to be written inside another style rule. This can keep component styles together, reduce repeated selectors, and make the relationship between parent and descendant selectors easier to see.

Native CSS nesting is part of CSS itself and does not require a preprocessor such as Sass or Less. Nested rules are interpreted directly by supporting web browsers.

Nesting Syntax

A nested style rule is written inside another style rule. The nested selector is evaluated in relation to the selector of its parent rule.

.card {
  padding: 20px;
  border: 1px solid #ccc;
  h2 {
    color: #0088cc;
  }
}

In this example, the h2 rule applies to <h2> elements that are descendants of elements with the card class.

The equivalent unnested CSS is:

.card {
  padding: 20px;
  border: 1px solid #ccc;
}
.card h2 {
  color: #0088cc;
}

Nesting keeps the heading rule with the component it belongs to while avoiding repetition of the parent selector.

Nested Selectors

Several selectors related to the same component can be nested inside its parent rule.

.card {
  padding: 20px;
  h2 {
    color: #0088cc;
  }
  p {
    line-height: 1.6;
  }
  a {
    font-weight: bold;
  }
}

This groups the styles for headings, paragraphs, and links belonging to the card without repeatedly writing .card.

Nesting is most useful when the nested rules have a clear relationship with their parent selector.

The & Nesting Selector

The & nesting selector represents the element or elements matched by the parent style rule. It is useful when the parent selector needs to appear explicitly within a nested selector.

.button {
  background-color: #0088cc;
  &:hover {
    background-color: #006699;
  }
}

The nested selector represents the hover state of .button. Its unnested equivalent is:

.button:hover {
  background-color: #006699;
}

The & makes the relationship to the parent selector explicit and is particularly useful for pseudo-classes and selectors that need the nesting selector in a specific position.

Nesting Pseudo-classes

Pseudo-classes can be nested with the & nesting selector to keep element states together with the element's base styles.

.link {
  color: #0088cc;
  &:hover {
    color: #006699;
  }
  &:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
  }
}

This keeps the normal, hover, and keyboard focus styles for the link in one related block.

The equivalent selectors are .link:hover and .link:focus-visible.

Nesting with Combinators

CSS combinators can be used with nesting to describe relationships between elements.

.navigation {
  > ul {
    margin: 0;
    padding: 0;
  }
  > ul > li {
    display: inline-block;
  }
}

The child combinator > limits the selectors to direct children instead of matching descendants at any depth.

The equivalent unnested CSS is:

.navigation > ul {
  margin: 0;
  padding: 0;
}
.navigation > ul > li {
  display: inline-block;
}

Other combinators can also be used when the intended element relationship requires them.

Multiple Levels of Nesting

Nested rules can contain additional nested rules.

.card {
  padding: 20px;
  .content {
    p {
      line-height: 1.6;
    }
  }
}

This corresponds to a selector relationship such as .card .content p.

Although deeper nesting is possible, excessive nesting can make selectors difficult to understand and can create unnecessary selector dependencies. Keeping nesting shallow usually produces CSS that is easier to maintain.

Nested Media Queries

Conditional group rules such as @media can be nested inside a style rule. This keeps responsive changes close to the styles they modify.

.card {
  padding: 20px;
  @media (min-width: 768px) {
    padding: 30px;
  }
}

The media query applies the larger padding to the same .card selector when the media condition is true.

This can be useful for component-based styles because the base declaration and its responsive adjustment can remain together.

Nesting and Specificity

Nesting changes how CSS is organized, but it does not remove the normal effects of the cascade and selector specificity. The resulting nested selector still participates in the cascade when the browser determines which declaration applies.

.card {
  a {
    color: #0088cc;
  }
}

The nested rule creates a selector relationship between .card and a. Other rules targeting the same link can still override it according to cascade origin, importance, cascade layers, specificity, scoping proximity when applicable, and source order.

Keep nested selectors as simple as practical rather than using nesting to build unnecessarily specific selectors.

CSS Nesting Practices

Practice Purpose
Group related rules Keeps component styles close to the parent selector they belong to.
Keep nesting shallow Prevents selectors from becoming unnecessarily complex.
Use & when the parent selector is needed Makes states and other selector relationships clear.
Use combinators intentionally Defines the required relationship between nested elements.
Watch selector specificity Helps prevent nested selectors from becoming harder to override.
Nest responsive rules when useful Keeps component-specific responsive changes near their base styles.

CSS Nesting Example

The following example keeps the styles for a card, its heading, and its link states together.

.card {
  padding: 20px;
  border: 2px solid #0088cc;
  h2 {
    margin-top: 0;
    color: #0088cc;
  }
  a {
    color: #0088cc;
    &:hover {
      color: #006699;
    }
  }
}

Open the example in the editor and change the nested heading or link styles. You can also add another nested selector inside .card and run the example again.

Play in Editor