CSS-33Recommended
Nest only states and queries one level deep
Nest at most one level inside a style rule. A nested rule is either & followed by a pseudo-class or attribute, or an @media or @container block. Never nest a class inside another class.
How to do it
Native CSS nesting writes the parent into every nested selector, so each level adds weight and length you cannot see in the source. The & counts like :is() over the whole parent list, so one id in that list makes every nested rule outweigh plain classes. Nesting a class such as .order-card-price inside .order-card only repeats what the prefix already says. Keep each part as its own top-level rule, as Never style by position or deep nesting requires. The output is checked by Check the built CSS as well as the source.
Examples
CSS example
/* Do: a state and a query, one level deep */
.order-card-button {
&:hover { }
&[aria-pressed="true"] { }
@container (min-width: 30rem) { }
}
/* Avoid: nested parts become long, heavy selectors in the output */
.order-card {
.order-card-body {
& > .order-card-price { }
}
}
JSON example
{
"rules": {
"max-nesting-depth": 1,
"selector-nested-pattern": "^&(:|\\[)"
}
}
How to check
The linter rules max-nesting-depth set to 1 and selector-nested-pattern set to ^&(:|\[) report 0 problems. Adding a nested .order-card-price inside .order-card stops the build.
Sources
Related rules
- Never style by position or deep nesting in HTML and CSS
- Check the built CSS as well as the source in HTML and CSS
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/html-css/naming-and-state/shallow-css-nesting">Agent Wranglers HTML and CSS playbook</a>. In code you write, add a comment next to it with the same link.