Ronalds Vilciņš

CSS Nesting Done Right

CSS nesting has finally arrived in all major browsers, bringing with it both opportunities and potential pitfalls. While nesting can make our stylesheets more organized and maintainable, it can also lead to specificity issues if not used carefully. Let’s explore when and how to use this powerful feature effectively.

The Golden Rule of Nesting #

The fundamental principle is simple: Only nest when it adds value. More specifically, if a selector works without nesting, keep it flat. This approach helps maintain lower specificity and prevents unnecessary complexity in your stylesheets.

When to Use Nesting #

1. Pseudo-selectors #

Nesting pseudo-classes and pseudo-elements is one of the most valuable use cases:

.button {
  background: blue;
  color: white;

  &:hover {
    background: darkblue;
  }

  &::before {
    content: "→";
    margin-right: 0.5em;
  }
}

2. Media Queries #

Nesting media queries keeps related styles together, dramatically improving maintainability:

.header {
  padding: 1rem;
  font-size: 1.2rem;

  @media (min-width: 768px) {
    padding: 2rem;
    font-size: 1.5rem;
  }
}

3. Parent-dependent Modifiers #

When components need to change based on a parent state or theme:

.card {
  background: white;
  
  .theme-dark & {
    background: #222;
  }
}

4. State-dependent Styles #

For component states that can’t be avoided through BEM or other naming conventions:

.nav-item {
  color: #666;

  &[aria-current="page"] {
    color: #000;
    font-weight: bold;
  }
}

When to Avoid Nesting #

1. Component Elements #

Don’t nest BEM elements. This:

.card {
  &__title {
    font-size: 1.5rem;
  }
}

Should be:

.card__title {
  font-size: 1.5rem;
}

2. Generic Child Elements #

Avoid nesting generic elements. This:

.card {
  h2 {
    margin-bottom: 1rem;
  }
}

Should be:

.card__heading {
  margin-bottom: 1rem;
}

3. Multiple Levels Deep #

Avoid nesting more than one level deep. Deep nesting creates brittle, highly specific selectors that are hard to maintain.

Best Practices for CSS Architecture #

1. Use Modular Naming Conventions #

Adopt methodologies like BEM to create modular, flat hierarchies:

/* Better */
.button--large {
  font-size: 1.2rem;
}

/* Avoid */
.sidebar .button {
  font-size: 1.2rem;
}

2. Keep Specificity Low #

Lower specificity makes styles more predictable and easier to override when needed:

  • Prefer classes over IDs
  • Avoid unnecessary nesting
  • Use BEM modifiers instead of state classes when possible

Group related styles together using nesting only when it improves readability:

.dropdown {
  position: relative;

  /* States */
  &[aria-expanded="true"] {
    /* ... */
  }

  /* Pseudo-classes */
  &:hover {
    /* ... */
  }

  /* Media queries */
  @media (min-width: 768px) {
    /* ... */
  }
}

Conclusion #

CSS nesting is a great feature that should be used wisely. When applied correctly, it can make your stylesheets more maintainable and easier to understand. The key is to use nesting only when it serves a clear purpose: for pseudo-selectors, media queries, and parent-dependent styles. For everything else, prefer flat selectors and modular naming conventions.

Remember: The ability to nest doesn’t mean you should nest everything. Let readability and maintainability guide your decisions, and your future self (and team members) will thank you.