How does CSS specificity work, and how is a conflict between two rules resolved?
When several rules target the same element, the browser resolves it in this order:
- Origin and importance. An
!importantdeclaration beats a normal one; author styles beat user-agent defaults. - Specificity, counted as three numbers — inline styles, then IDs, then classes, attribute selectors and pseudo-classes, then elements and pseudo-elements. So
#nav .item(1,1,0) beats.header .nav .item(0,3,0), because any number of classes cannot outweigh a single ID. - Source order. If specificity ties, the rule that appears later wins.
Things that catch people out:
- The universal selector
*and combinators such as>and+add nothing. :not()itself adds nothing, but its argument counts.:where()always has zero specificity, which makes it excellent for defaults that should be easy to override.
Note: The right conclusion is that you should keep specificity flat rather than win specificity battles. Escalating to !important is a symptom, and it makes the next override worse.





