CSS Selectors Specificity
CSS specificity is a system used by browsers to determine which CSS rule takes precedence when multiple rules target the same HTML element. Understanding specificity helps in debugging and writing maintainable, conflict-free styles.
π’ How Specificity is Calculated
Specificity is calculated based on a four-part value: a, b, c, d
, where:
a
β Inline styles (added directly to the element using thestyle
attribute)b
β Number of ID selectorsc
β Number of class selectors, attributes selectors, and pseudo-classes (.class
,[type="text"]
,:hover
, etc.)d
β Number of type selectors and pseudo-elements (div
,p
,::before
, etc.)
These are not added numerically but compared from left to right, just like comparing version numbers.
π Examples of Specificity
Selector | Specificity (a,b,c,d) |
---|---|
#header | (0,1,0,0) |
.nav .item | (0,0,2,0) |
div p span | (0,0,0,3) |
ul#menu li.active a:hover | (0,1,2,3) |
style="color:red" (inline style) | (1,0,0,0) |
βοΈ Conflict Resolution: Who Wins?
When multiple rules target the same element:
- Higher specificity wins
- If specificity is equal, later rule in the CSS wins (source order)
!important
overrides specificity β but should be avoided for maintainability
π¨ Common Mistakes and Gotchas
- Using multiple class selectors doesn't beat an ID selector.
- Inline styles always override external CSS unless
!important
is used. !important
can override even higher specificity, but only within the same property.
π οΈ Tips for Managing Specificity
- Prefer class selectors for flexibility and reusability.
- Avoid overusing IDs in styling β they're too specific and hard to override.
- Use CSS methodologies like BEM (Block Element Modifier) to keep specificity low and predictable.
- Avoid
!important
unless absolutely necessary (e.g., utility classes or third-party overrides).
π‘ Specificity Hierarchy (Lowest to Highest)
- Universal selector (
*
), combinators (+
,>
,~
), and pseudo-element::before
,::after
(0,0,0,0 or 0,0,0,1) - Element selectors (
div
,h1
) (0,0,0,1) - Class, attribute selectors, pseudo-classes (
.btn
,[type="text"]
,:hover
) (0,0,1,0) - ID selectors (
#main
) (0,1,0,0) - Inline styles (
style="..."
) (1,0,0,0) !important
(overrides everything but is not part of specificity calculation)
So, understanding specificity is essential for writing clean, conflict-free CSS. It helps in predicting how styles will be applied and avoiding unnecessary overrides or use of
!important
. In real-world projects, I follow naming conventions and modular CSS approaches to keep specificity low and my styles scalable.