Understanding specificity in CSS

Understanding specificity in CSS

In the process of writing CSS code, you will invariably run into situations where the code you just wrote seems to have absolutely no effect at all on the page. This can be frustrating, confusing and difficult to troubleshoot without the aid of something like Chrome Developer Tools. However, having a better understanding of how specificity and the cascade in CSS works can go a long way in mitigating these issues altogether. This blog post will aim to point out some of the main issues that typically come up when trying to determine which piece of code is blocking what you’re trying to do.

It is well known that CSS (which stands for Cascading Style Sheets) works from the top down. This means that, generally speaking, code that is further down in the document takes precedence over other code higher up. A simple example of this is having two declarations targeting the same element:

 

p {
  color: blue;
}
p {
  color: green;
}

 

The color of paragraph elements in this example will always be green, since it appears after the declaration assigning the color of blue to paragraphs.

The problem is that selectors beyond just element selectors have varying levels of specificity, and combining selectors will increase their specificity, overriding other rules.

Elements and pseudo-elements

Elements and pseudo-elements have the lowest level of specificity. Since they target all instances of a given element, using element selectors should only be used when you really want those styles to be applied to all instances of paragraphs, divs, headers, etc. For example, the following code will apply a 1px solid black border to all paragraph elements in the document.

 

p {
  border: 1px solid black;
}

 

Classes, attributes and pseudo-classes

Classes, attributes and pseudo-classes have a higher level of specificity, and will only apply to elements associated with them. They are reusable, in the sense that you can have classes applied to multiple different elements, whenever you want them to share the same styles. These styles will also override styles that conflict with those at the element level. In the example below, all paragraph elements will be green, except for any with the class of alert, which will be red:

 

p {
  color: green;
}
p.alert {
  color: red;
}

 

IDs

IDs have one of the highest levels of specificity, and will override almost anything. Unlike classes which can be reused as many times as you want, IDs are only supposed to be applied to a single element on the page.

 

p#myParagraph {
  color: black;
}
p.alert {
  color: red;
}
p {
  color: green;
}

 

Even though there are two further declarations for paragraphs underneath the p#myParagraph declaration, the ID of #myParagraph will always be black.

Inline styles

Inline styles have an even higher level of specificity than IDs. While it is generally very frowned upon to apply any styles inline, as it makes it difficult to find and manage the styles applied to elements, there are situations where it can be justified.

 

<p style="color: red;">My red paragraph</p>

 

The above inline style will always be red, regardless of what styles are applied elsewhere.*

!important

The one caveat to the above, even including inline styles, is the use of !important. Whenever !important is added to a CSS rule, this rule will take precedence over all else, always, no matter what:

 

p {
  color: blue !important;
}

 

!important can be a lifesaver when you cannot figure out what is blocking your CSS, but it can also be easily abused and just make your code more of a mess. As a general rule, use !important only when all else fails.

An extremely handy tool for better understanding and checking specificity is Keegan Street’s Specificity Calculator. Whenever in doubt, it can very useful to check your selectors here.

Resources

Post a Comment

Comments are moderated. Your email is kept private. Required fields are marked *

© 2019 Sunlight Media LLC