CSS Tutorial
CSS Specificity
When two CSS rules target the same element with conflicting values, specificity decides which one wins. It is a scoring system based on the kinds of selectors you use. Understanding specificity is the single best way to stop fighting your own stylesheets and to debug why a style is not applying. This guide breaks the rules down clearly.
What is Specificity?
Specificity is the weight a browser assigns to a selector to resolve conflicts. When multiple rules set the same property on one element, the browser applies the rule with the highest specificity. If two rules tie, the one that appears later in the CSS wins (the cascade). More specific selectors beat less specific ones regardless of order.
The Specificity Hierarchy
Think of specificity as columns of a score, from most to least powerful. A higher category always beats any amount of a lower one.
| Selector type | Specificity weight | Example |
|---|---|---|
| Inline style | Highest (1,0,0,0) | style="color:red" |
| ID | (0,1,0,0) | #header |
| Class, attribute, pseudo-class | (0,0,1,0) | .btn, [type], :hover |
| Element, pseudo-element | (0,0,0,1) | div, ::before |
| Universal selector * | 0 (adds nothing) | * |
How Specificity is Calculated
Count the IDs, then the classes/attributes/pseudo-classes, then the element selectors in a rule. Write it as three (or four, including inline) numbers and compare left to right, like version numbers. The bigger left-most number wins.
p { } /* 0,0,1 - one element */
.intro { } /* 0,1,0 - one class */
#main { } /* 1,0,0 - one ID */
#main p.intro { } /* 1,1,1 - id + class + element */
ul li a:hover { } /* 0,1,3 - three elements + one pseudo-class */Live Example: A Specificity Battle
The paragraph below is targeted by four rules that all set color. Even though the element and class rules come later in the source, the ID selector wins because it has the highest specificity.
<!DOCTYPE html>
<html>
<head>
<style>
p { color: gray; } /* 0,0,1 */
.msg { color: blue; } /* 0,1,0 */
#hero { color: green; } /* 1,0,0 - wins */
body p { color: orange; } /* 0,0,2 */
</style>
</head>
<body>
<p id="hero" class="msg" style="font-family:system-ui,sans-serif;">
Four rules fight over my color - the #hero ID wins, so I am green.
</p>
</body>
</html>To make a rule win, prefer adding a class over adding an ID or an !important. Classes keep specificity low and manageable; IDs and !important create escalating wars that are hard to unwind.
Order Only Matters on a Tie
Source order is the tie-breaker, not the first rule of judgment. A later rule only wins if it has equal specificity to the earlier one. A single class (0,1,0) will always beat ten element selectors stacked together, no matter where each appears.
<!DOCTYPE html>
<html>
<head>
<style>
html body div p span.tag { color: gray; } /* 0,1,5 */
.tag { color: crimson; } /* 0,1,0 - later, ties on class count? */
</style>
</head>
<body>
<div><p><span class="tag" style="font-family:system-ui;">
The long selector has more elements, so it wins over the lone class.
</span></p></div>
</body>
</html>!important overrides normal specificity entirely and should be a last resort. Two !important declarations then fall back to comparing their specificity against each other, which quickly gets confusing.
Key points
- Specificity decides which conflicting rule applies; higher specificity wins.
- The order of power is inline > ID > class/attribute/pseudo-class > element.
- A higher category always beats any number of lower-category selectors.
- Source order only breaks ties between equally specific rules.
- Prefer low-specificity class selectors over IDs and !important to stay maintainable.
