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
3. Organize Related Styles
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.