Nesting Pitfalls

Avoid over-nesting that creates bloated, over-specific CSS.

Nesting is powerful but easy to overuse. Deep nesting produces long selectors that are hard to override and increase file size.

The inception rule

A common guideline: do not nest more than three levels deep. If you find yourself nesting further, your selectors are probably too tied to HTML structure.

Watch out for

  • Specificity creep.a .b .c .d is hard to beat later.
  • Fragile selectors — changing HTML nesting breaks the CSS.
  • Bloated output — every level repeats the ancestor chain.

Prefer flat, class-based selectors (like BEM) and reserve nesting for states and direct relationships.

Example

Example · css
// AVOID: too deep, over-specific
.page {
  .content {
    .article {
      .title { color: #CC6699; } // .page .content .article .title
    }
  }
}

// PREFER: flat and reusable
.article__title {
  color: #CC6699;
}

When to use it

  • A developer refactors a stylesheet where every rule was nested 5 levels deep, generating overly specific selectors that blocked simpler overrides.
  • A code reviewer flags a block nested inside .page > .section > .container > .grid > .card as too deep and suggests flattening to two levels max.
  • A team adopts a linting rule (max-nesting-depth: 3) to catch over-nesting in CI before it ships to production.

More examples

Over-nested vs flat equivalent

Shows how deep nesting produces an unnecessarily high-specificity selector that a BEM class name replaces with a single flat rule.

Example · css
// Avoid — 4 levels deep, high specificity
.page .sidebar .widget .title {
  font-size: 1rem;
}

// Prefer — flat with BEM modifier
.widget__title {
  font-size: 1rem;
}

Two-level nesting guideline

Limits nesting to one BEM element and one state modifier at most, keeping specificity low and selectors readable.

Example · css
// Good: max two meaningful levels
.card {
  padding: 1rem;

  &__title {
    font-size: 1.25rem;
  }

  &:hover {
    box-shadow: 0 4px 8px rgba(0,0,0,.1);
  }
}

Inline media query stays shallow

Nests a media query directly inside .hero rather than inside a nested child, preventing specificity from compounding.

Example · css
.hero {
  font-size: 1.5rem;

  @media (min-width: 768px) {
    font-size: 2.5rem; // not further nested
  }
}

Discussion

  • Be the first to comment on this lesson.