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 .dis 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
// 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.
// 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.
// 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.
.hero {
font-size: 1.5rem;
@media (min-width: 768px) {
font-size: 2.5rem; // not further nested
}
}
Discussion