When two rules target the same element with the same property, the browser picks a winner by specificity — roughly, how "precise" the selector is:
- Inline styles (
style="...") — highest. - ID selectors (
#logo). - Class, attribute, and pseudo-class selectors (
.card,[type],:hover). - Type selectors and pseudo-elements (
p,::before) — lowest.
CSS
p { color: black; } /* specificity: 1 type selector */
.intro { color: blue; } /* specificity: 1 class — wins over p */
#hero p.intro { color: red; }/* 1 id + 1 type + 1 class — wins over both */More selectors of the same kind add up — .a.b (two classes) beats
.a (one class) beats .parent .child combined only if .parent .child
has fewer classes total. When specificity ties, the rule that appears
later in the stylesheet wins.
!important
Appending !important to a declaration overrides normal specificity —
it wins regardless of how "weak" its selector is, until another
!important rule with higher specificity comes along.
CSS
p { color: black !important; }Treat !important as a last resort: it makes future overrides harder
and is a common sign that the underlying specificity/architecture needs
fixing rather than patching over.