CSS Specificity

CSS specificity is the scoring system browsers use to decide which CSS rule applies when several selectors target the same element.

Summarize this

What is CSS specificity?

CSS specificity is the algorithm a browser uses to choose which declaration wins when two or more rules target the same element with conflicting values. Each selector receives a weight, and the heavier selector applies, whatever its position in the stylesheet. Understanding it explains most of the "why is my style not applied?" situations in front-end work.

How specificity is calculated

Specificity is usually written as three or four numbers, from the strongest to the weakest category:

  • Inline styles (the style attribute) beat any selector.
  • IDs such as #header count in the first column.
  • Classes, attributes and pseudo-classes such as .card, [type="text"] and :hover count in the second.
  • Elements and pseudo-elements such as div and ::before count in the third.

The universal selector * and combinators add nothing. Columns are compared left to right and never carry over: ten classes never beat one ID.

Example in code

p { color: black; } scores (0,0,1).

.intro { color: blue; } scores (0,1,0).

#hero .intro { color: red; } scores (1,1,0).

On a paragraph with the class intro inside #hero, the text is red, even if the black rule is written last.

Specificity scores at a glance

SelectorScore (ID, class, element)Comment
*0,0,0No weight
li0,0,1Element selector
.menu li0,1,1One class and one element
a:hover0,1,1Pseudo-class counts as a class
#nav a1,0,1One ID outweighs any number of classes

Specificity, the cascade and !important

Specificity is only one step of the cascade. The browser first compares origin and importance (!important wins), then cascade layers, then specificity, and finally source order when scores are equal. Overusing !important is a trap: the only way to override it is another !important with higher specificity, which quickly makes a stylesheet unmaintainable.

Modern tools to control specificity

  • :where() always has zero specificity, which is ideal for resets and defaults.
  • :is() and :not() take the specificity of their most specific argument.
  • @layer lets you order groups of rules explicitly, so a base layer never beats a component layer.
  • CSS variables reduce the need for overrides by changing a value instead of a selector.

Best practices

  • Style with classes, not IDs or deep descendant chains.
  • Keep selectors short and flat, and use a naming convention such as BEM.
  • Avoid !important except for utilities that must always win.
  • Check the computed rule in the browser DevTools before adding more weight.

CSS specificity at BeBranded

When we build sites in Webflow, we follow a class-first approach with a consistent naming system, which keeps specificity low and predictable and makes redesigns safer. Discover our website service.

FAQ

CSS specificity is the weight given to a selector. When several rules conflict on the same element, the one with the highest specificity is applied.
Count inline styles, then IDs, then classes, attributes and pseudo-classes, then elements and pseudo-elements. Columns are compared from left to right and never carry over.
Yes. A single ID outweighs any number of classes, because the ID column is compared before the class column.
The rule that appears last in the source order wins, unless a cascade layer or !important changes the outcome.
It overrides normal specificity, so the only way to beat it is another !important. This creates conflicts that are hard to debug and maintain.
The :where() pseudo-class always has zero specificity. It is useful for defaults and resets that must stay easy to override.

Ready to boost your conversions?

Our team is here to understand your needs & work with you to create your next projects.
Get news, infos and resources.
Actionable tips delivered straight to your inbox.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.