CSS Selectors

Tyler Knight
Aug 22, 2017 · 4 min read

If at any point you find yourself frustrated as to why your CSS isn’t working correctly, there’s a decent chance it’s because your style is getting overridden somehow. Specificity is generally the biggest pain for anyone trying to figure out CSS, but once you know the general rules it saves you a lot of headache.

There are 4 basic categories that affect your specificity. The more of each of these you have on a selector the higher the specificity level. Certain categories hold higher precedence and no matter how many of a lower category you have, the higher category will override it. Below they are ranked by the least level of precedence to the most.

  1. Elements
  2. Classes & Attributes
  3. IDs
  4. Inline Styles

Elements

Element selectors are the base level, just selecting whatever tag you call. The more element selectors you include, the higher it will rank in specificity. Elements also include pseudo elements like ::first-letter or ::before

<style>
a {color: red;}
p a {color: blue;}
div p a {color: green;}
</style>
<a href="#">This is a link.</a><p>
<a href="#">This is another link.</a>
</p>
<div>
<p>
<a href="#">This is a nested link.</a>
</p>
</div>
results

Classes, Attributes

Class selectors and attribute selectors are the next step up in specificity level. This include .classes, [attributes] as well as pseudo classes like :hover.

<style>
div p a {color: green;}
a[alt] {color: red;}
.cool-link {color: blue;}
a[alt].cool-link {color:black;}
</style>
<div>
<p>
<a href="#" alt="this link">This is a link.</a><br>
<a href="#" class="cool-link">This is cool link.</a><br>
<a href="#" alt="another link" class="cool-link">This is another link.</a>
</p>
</div>
results

IDs

Because you should only have one ID per page, these #id selectors hold the second highest level of precedence, overwriting any other class or attribute styles you may have on an element.

<style>
div p a {color: green;}
a[alt] {color: red;}
.cool-link {color: blue;}
a[alt].cool-link {color:black;}
#main-link {color: purple;}
</style><div>
<p>
<a href="#" alt="another link" class="cool-link">This is another link.</a><br>
<a href="#" alt="main link" class="cool-link" id="main-link">This is main link.</a>
</p>
</div>
results

Inline Styles

Finally, the highest level of precedence is the inline tag styles. No matter how many classes, IDs or element selectors you have in your CSS file, if you write a style attribute on any HTML tag, those styles will take action.

<style>
div p a {color: green;}
a[alt] {color: red;}
.cool-link {color: blue;}
a[alt].cool-link {color:black;}
#main-link {color: purple;}
</style>
<div>
<p>
<a href="#" alt="another link" class="cool-link">This is another link.</a><br>
<a href="#" alt="main link" class="cool-link" id="main-link">This is cool link.</a><br>
<a href="#" style="color:orange;" alt="main link" class="cool-link" id="main-link">This is link.</a>
</p>
</div>
results

Conclusion

So as you can see, selectors in CSS follow a hierarchy. That hierarchy along with the amount of pieces included to a selector determine which CSS acts on the element. While there are several more selector helpers that can come into play, these are the most basic pieces. It’s also worth noting that if there are two selectors with the same amount of specificity, the browser will always render the one that is further down in your code. This is why it’s important to know the order in which you link your stylesheets to your front end to ensure that you don’t have any overriding issues. Below is a chart that you can use to calculate your selector’s specificity taken directly from w3.org to help reaffirm these concepts.

From https://www.w3.org/TR/CSS2/cascade.html:

A selector’s specificity is calculated as follows:

count 1 if the declaration is from is a ‘style’ attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element’s “style” attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)

count the number of ID attributes in the selector (= b)

count the number of other attributes and pseudo-classes in the selector (= c)

count the number of element names and pseudo-elements in the selector (= d)

The specificity is based only on the form of the selector. In particular, a selector of the form “[id=p33]” is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an “ID” in the source document’s DTD.

Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.

calculated specificity examples from https://www.w3.org/TR/CSS2/cascade.html

Sources

  1. https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/
  2. https://www.w3.org/TR/CSS2/cascade.html
  3. http://bigemployee.com/4-simple-techniques-to-quickly-debug-and-fix-your-css-code-in-almost-any-browser/
)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade