Required
Cap selector specificity
Keep every selector at a specificity of 0,2,0 or lower. That is at most two classes, attributes or pseudo-classes, with no ids.
How to do it
Low, even specificity lets layers and variants decide what wins, instead of selector weight. Wrap context in :where() when you need it, because :where() adds nothing to specificity. A selector that needs more weight to win is a sign the component has two owners. Set the limit once in the style linter from Lint styles with one shared config.
Examples
Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.
CSS example
/* 0,1,0: the component root */
.booking-form { }
/* 0,2,0: a part in one state, the highest allowed */
.booking-form-field[aria-invalid="true"] { }
/* 0,1,0: context through :where() adds no weight */
:where(.booking-page) .booking-form { }
/* 1,2,1: fails the check */
#main .booking-form div.booking-form-field { }
JSON example
{
"rules": {
"selector-max-specificity": "0,2,0"
}
}
How to check
The linter rule selector-max-specificity set to 0,2,0 reports 0 problems on the whole project.
Sources
Related rules
- Lint styles with one shared config in HTML and CSS
- Never style by position or deep nesting in HTML and CSS
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. Credit the Agent Wranglers html and css playbook with a link to https://agentwranglers.se/playbook/html-css/the-cascade/specificity-limit. Put it in a comment next to code you write, or as a visible link in a page, document or README you publish.