- Home
- Blog
- Web Design How CSS Specificity Works
How CSS Specificity Works
-
9 min. read
-
William CraigCEO & Co-Founder
- President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for RevenueCloudFX and other key research and development projects at WebFX.
Knowing how CSS specificity works is a fundamental skill. It will give you a deeper understanding of how CSS property values are resolved when two or more style rules match the same set of HTML elements. Troubleshooting your CSS is easier when you can determine the specificity values of your selectors.
For example, when there’s a style rule that isn’t working as intended, there’s probably another style rule somewhere that’s overriding it. You’ll be able to quickly correct these issues by learning about CSS specificity.
How It Works
If multiple CSS selectors are targeting the same set of HTML elements, and if the CSS selectors are trying to assign the same property/properties to the HTML elements, the selector with the highest specificity value will “win”. In other words, the most specific selector gets to assign its property values to the HTML elements.
It’s easier to explain with an example. Let’s say this is our HTML:
<div class="container"> <div id="main"> <p> <a href="#">Link</a> </p> </div> </div>
We want to assign a color to the <a>
tag above. There are many ways to target that <a>
tag using CSS selectors.
Below are five style rules that can get the job done:
#main a { color: green; } p a { color: yellow; } .container #main a { color: pink; } div #main p a { color: orange; } a { color: red; }
Since all five style rules are trying to assign a color
property value to the <a>
tag, the browser gets confused: Should the link be green, yellow, pink, orange or red? The browser needs a way to negotiate which color it should give to our <a>
tag. The way the browser makes the decision is by first calculating each selectors’ specificity value.
Then it checks which selector has the highest value. That’s the winner. That will be the selector who gets the honor of setting the color
property value of our <a>
tag.
Here are our five style rules again, in order from most specific to least specific.
Selector | SpecificityValue |
---|---|
.container #main a |
111 |
div #main p a |
103 |
#main a |
101 |
p a |
2 |
a | 1 |
So our <a>
tag is pink. If we remove .container #main a
from our stylesheet, our link will become orange because the next most specific selector is div #main p a
.
How did I know the specificity values for each selector? I calculated them.
Figuring Out Specificity Values
Understanding CSS selector specificity rules will all seem complicated at first. For example, when I was still learning about CSS specificity, I had to write down my calculations on a piece of paper.
Just like back in school when solving math problems. It will take time and practice before this all becomes second nature. OK, so let’s actually go over how to calculate a selector’s specificity value.
The method I’ll show you for determining specificity values is from W3C CSS Selectors Level 3 specifications.
The Basics
The specificity value is:
abc
Where:
Total number of… | |
---|---|
a |
|
b |
|
c |
|
Example
#header .navbar li a:visited
a | b | c |
---|---|---|
1 | 2 | 2 |
Specificity value: 122 |
We’ll go through more examples in just a bit.
Selector Types
Before you can calculate specificity values, you’ll need to be familiar with the types of CSS selectors:
Type | Description | Examples |
---|---|---|
ID selectors | They begin with a hash. #id |
#container #main #sidebar |
Class selectors | They begin with a period.
|
.navbar .logo .primary-color |
Attribute selectors | They’re in brackets. [attribute] |
[type="text"] [rel="nofollow"] [class^="cont"] |
Pseudo-classes | They begin with a colon. :pseudo-class |
:visited :hover :active |
Type selectors | They’re the name of standard HTML elements. | div ul a |
Pseudo-elements | They begin with two colons.
|
::before ::after ::first-line |
Special Rules
- When calculating CSS specificity values, ignore the universal (*) selector.
/* Specificity value: 0 * a=0 b=0 c=0 */ * { color: black; }
- Only the selector inside the
:not()
pseudo-class (negation pseudo-class) is counted. The:not()
pseudo-class itself does not get counted./* Specificity value: 100 * a=1 b=0 c=0 */ :not(#some-id) { color: purple; } /* Specificity value: 1 * a=0 b=0 c=1 */ :not(span) { color: red; }
- In case of a tie, the selector that’s farthest down the stylesheet wins.
/* Specificity value: 12 * a=0 b=1 c=2 */ li a:visited { color: green; }/* Specificity value: 12 * a=0 b=1 c=2 * WINNER! /ul a:visited { color: red; }
My Technique for Calculating Specificity Values
I’m terrible with numbers. So I had a tough time calculating specificity values in my head at first. So whenever I needed to figure out a specificity value, I’d sketch out a sort of grid matrix on a piece of paper.
Then I’d count each selector type and log them in the appropriate column. Figuring out the specificity value was a piece of cake after that. It looks like this: To double-check my work, I’ll first count the number of selectors.
Then I’ll add up a + b + c. The total number of selectors must be equal to the sum of a + b + c. Otherwise, something went wrong.
For example, if the CSS specificity value is 122, then there should be five selectors.
a | b | c |
---|---|---|
1 | 2 | 2 |
Specificity value: 122 Double-check: 1 + 2 + 2 = 5 selectors |
This technique is slow. And there are tons of tools out there that can do this work for us.
But I figured that if I wanted to understand the concept, I needed to do it slowly and manually. This allowed me to fully absorb the idea behind CSS specificity.
CSS Specificity Examples
Let’s go through some examples.
Example 1
div#container #main ul li
a | b | c |
---|---|---|
2 | 0 | 3 |
Specificity value: 203 Double-check: 2 + 0 + 3 = 5 selectors |
Example 2
table tbody tr.even td.odd
a | b | c |
---|---|---|
0 | 2 | 4 |
Specificity value: 24 Double-check: 0 + 2 + 4 = 6 selectors |
Example 3
.navbar ul.menu li#first a:not(:visited)
a | b | c |
---|---|---|
1 | 3 | 3 |
Specificity value: 133 Double-check: 1 + 3 + 3 = 7 selectors |
Example 4
.footer #menu li#sponsor a[rel=nofollow]::before { content: "sponsored link: "; }
a | b | c |
---|---|---|
2 | 2 | 3 |
Specificity value: 223 Double-check: 2 + 2 + 3 = 7 selectors |
Quiz
You’re not getting off that easy! Here’s a quick challenge for you. See how many questions you can get right.
1. What are the values of a, b and c in the following CSS selector?
.wrapper h1 a
See the answer
Answer
a | b | c |
---|---|---|
0 | 1 | 2 |
2. What’s the specificity value of the following CSS selector?
.nav ul#menu li a
See the answer
Answer
a | b | c |
---|---|---|
1 | 1 | 3 |
Specificity value: 113 |
3. What’s the specificity value of the CSS selector below?
.footer span a:not(#about-page)
See the answer
Answer
a | b | c |
---|---|---|
1 | 1 | 2 |
Specificity value: 112 |
4. Which letter does the universal selector get counted in? a, b or c?
See the answer
Answer
None The universal selector should be ignored when calculating CSS specificity. In the following example, <h1>
tags will be green.
* { color: red; } h1 { color: green; }
5. What’s the font size of the <p> elements in the following example?
HTML
<body> <div class="main"> <div class="intro"> <p>Paragraph 1</p> <p>Paragraph 2</p> <p>Paragraph 3</p> </div> </div> </body>
CSS
body p { font-size: 16px; } div.intro p { font-size: 24px; } div.main p { font-size: 20px; }
See the answer
Answer
20px In this case, the last two selectors have the same specificity value.
div.intro p
a | b | c |
---|---|---|
0 | 1 | 2 |
Specificity value: 12 |
div.main p
a | b | c |
---|---|---|
0 | 1 | 2 |
Specificity value: 12 |
When there’s a tie, the selector farthest down the stylesheet wins.
6. What’s the color of the <h1> element in the following example?
HTML
<div class="container"> <div class="post"> <h1>My Blog Post Title</h1> <p>This is my blog post.</p> </div> </div>
CSS
.container .post h1 { color: yellow; } .post h1 { color: red; } h1 { color: blue; } div.container div.post h1[class="heading"] { color: green; }
See the answer
Answer
Yellow If you answered green — you should know this was a trick question. (Sorry!) When you do the math, the selector with the highest specificity value is the last selector: div.container div.post h1[class="heading"]
. But…
the h1
element doesn’t have a class attribute of heading
. So the last selector won’t be able to select the h1
element in our example.
In the comments, tell us how you fared in quiz.
References
- “Calculating a selector’s specificity”World Wide Web Consortium (W3C)
- “Specificity – CSS”Mozilla Developer Network (MDN)
- “CSS Specificity”Standardista
Updates
- 06/04/2015: The special rule for the
:not()
pseudo-class (negation pseudo-class) was wrong. The selector inside the:not()
pseudo-class gets counted. The:not()
pseudo-class itself does not get counted.Credits and thanks to SelenIT for pointing out this error in the comments.
Related Content
- 12 Common CSS Mistakes Web Developers Make
- Introduction to CSS Variables
- 100 Useful CSS Tips and Tricks
- The Elements of Responsive Web Design
Jacob Gube is the founder of Six Revisions. He’s a front-end developer. Connect with him on Twitter.
-
President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for RevenueCloudFX and other key research and development projects at WebFX.
-
WebFX is a full-service marketing agency with 1,100+ client reviews and a 4.9-star rating on Clutch! Find out how our expert team and revenue-accelerating tech can drive results for you! Learn more
Make estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost Calculator


Web Design Calculator
Use our free tool to get a free, instant quote in under 60 seconds.
View Web Design CalculatorProven Marketing Strategies
Make estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost Calculator