⚡IntermediateModern CSS

CSS Nesting

Write cleaner, less repetitive CSS by nesting child rules inside parent rules natively, with no preprocessor required.

Overview

CSS nesting available natively in all modern browsers since 2023 lets you write child rules inside parent rules, just like Sass or Less, but without any build tool. ```css /* Without nesting */ .card { ... } .card h3 { ... } .card p { ... } .card:hover { ... } .card .btn { ... } /* With nesting */ .card { ... h3 { ... } /* descendant: .card h3 */ p { ... } /* descendant: .card p */ &:hover { ... } /* compound: .card:hover */ .btn { ... } /* descendant: .card .btn */ } ``` The `&` (ampersand) represents the parent selector: - `& h3` = `.card h3` (same as just writing `h3` inside) - `&:hover` = `.card:hover` (compound no space) - `.parent &` = `.parent .card` (reversal & as a descendant) - `&.active` = `.card.active` (multi-class compound)

Key Points

  • •Nested rules without & are treated as descendants: h3 inside .card = .card h3
  • •& is required for compound selectors: &:hover = .card:hover (not .card :hover)
  • •&.active selects an element that has both .card and .active classes
  • •.dark-mode & puts the parent (.card) inside .dark-mode "reverse nesting"
  • •@media queries can be nested inside rules since modern CSS 2023
  • •Nesting can go multiple levels deep, but 2-3 levels is usually the limit for readability
  • •Supported in Chrome 112+, Firefox 117+, Safari 16.5+ (all modern browsers)

Examples

Component nesting

.btn {
  padding: 10px 20px;
  border-radius: 8px;
  border: none;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease;

  /* Compound (modifier) selectors */
  &.btn-primary {
    background: #6366f1;
    color: white;

    &:hover { background: #4f46e5; }  /* .btn.btn-primary:hover */
  }

  &.btn-outline {
    background: transparent;
    border: 2px solid #6366f1;
    color: #6366f1;

    &:hover { background: #eef2ff; }
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

Nested media queries

.hero-title {
  font-size: 1.5rem;
  font-weight: 800;

  /* Media query nested inside the rule */
  @media (min-width: 768px) {
    font-size: 2.5rem;
  }

  @media (min-width: 1024px) {
    font-size: 3.5rem;
  }
}

Nesting @media inside a rule keeps all styles for one element in one place no need to scroll to find breakpoints.

Parent selector reversal with &

.icon {
  color: #6b7280;

  /* .dark-mode .icon */
  .dark-mode & {
    color: #94a3b8;
  }

  /* .card:hover .icon */
  .card:hover & {
    color: #6366f1;
    transform: scale(1.1);
  }
}

Placing & after the parent means "an .icon that is a descendant of .dark-mode" the reverse of normal nesting.

Common Mistakes

  • Forgetting & for pseudo-classes: writing ":hover" instead of "&:hover" targets any element inside, not the parent itself
  • Nesting too deeply 4+ levels of nesting creates specificity problems and hard-to-read CSS
  • Expecting nesting to work in older browsers add a PostCSS nesting plugin for IE11 or older Edge

Note

The single greatest benefit of native nesting is co-location all styles for a component live together, making it trivial to delete a component without leaving orphan CSS. Think of it as CSS scoping for free.

Exercises

Write CSS to style the HTML scaffold. The preview updates live — when it looks right, mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

Inside a CSS nesting block, what does "&:hover" compile to?