Thursday, October 31, 2019

What is CSS Specificity and How Does it Work?

What is CSS Specificity and How Does it Work?

When working with CSS conflicting styles can be a thorn in your side, especially when you don’t know where the conflict is originating from. This tutorial will give you a firm understanding of CSS specificity which will help fill in any knowledge gaps so you don’t end up pulling your hair out of frustration.

Note: perhaps you’re a seasoned CSS pro? This is a topic developers have enjoyed talking about since the earliest days of CSS, but it’s always fun to refresh your memory!

Everything You Need to Know About CSS

This tutorial is part of our Learn CSS: The Complete Guide—check it out and get bookmarking!

What is CSS Specificity?

MDN put it nicely (as always):

“Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied.”

That means that CSS specificity is a set of rules used by browsers in determining which of the developer-defined styles will be applied to a specific element. For a style to be applied to a particular element, the developer has to abide by the rules, so that the browser knows how to apply the style.

Frustrated at CSS specificity
Come on mate, it’s not that bad

When two or more styles target a particular element, the style with the highest specificity is the one that gets applied.

Understanding the Hierarchy of CSS Specificity

The specificity of a style is dependent on where the selector ranks when compared to other conflicting selectors. Selectors define how you target the element you want to style in CSS. Let’s look at the selectors in the hierarchy of highest to lowest:

Inline Styles

These are styles defined in the HTML document, directly attached to the element that’s to be styled. For example:

These kinds of styles are not commonly used as it’s considered best practise to “separate concerns” and have your styles in an external stylesheet. Yet, in the hierarchy of styles, inline styles rank highest.

ID Selectors

ID selectors are the next in the queue. These are selectors that target an element using the element’s ID. IDs are unique; an element can have just one ID, and that ID can be used only once within an HTML document.

They can be overridden by inline styles.

Classes, Attributes, and Pseudo Classes

ID selectors are followed by class selectors, attribute selectors, and pseudo-class selectors. Here’s some example markup, showing corresponding CSS selectors with each one:

Elements and Pseudo Elements

Element selectors allow you style the selected element, while pseudo-element selectors let you style part of the selected element.

These selectors rank lowest in the hierarchy of CSS specificity.

Using Rank to Score CSS Specificity

To calculate the specificity of a style, we’ll start at 0 for each rank. We can then increment the rank based on the selectors used to target the element. Here’s how our starting point looks:

specificity score of 0000

For inline styles we’ll have a specificity scored like this:

inline style specificity score of 1000

In this case, an inline style is given a score (in the simplest terms) of 1000. A single ID selector would have a 1 added to the box underneath ID, effectively giving a score of 0100. Let’s look at some specific examples to make it clearer.

CSS Specificity Rules and Examples

Class Selectors Override Multiple Element Selectors

Let’s say we have a snippet like this in our HTML markup–an h1 heading nested in two div elements:

And in our CSS we have the following two styles, both targeting the same h1 heading:

Which do you think will be applied? In this case, we have one class selector:

score of 0010

 versus three element selectors:

specificity score of 0003

10 against 3 specificity points. Red wins:

Even if you have more elements within your selector, the style applied using classes will be chosen.

The Last Rule Wins

What do you think happens when you target an element using exactly the same selectors and make use of different styles. Something like the example below?

Take a wild guess.

The lower one (the most recently processed style rule) is viewed as being “closest to the element” and therefore the most specific in this case. Based on that fact, it gets applied to the element. This also applies to all cases where the selectors used have equal CSS specificity.

Below is an example of us making use of elements and pseudo-elements selectors–selectors with equal specificity.

The style applied to the element, in this case, is the last style.

ID Selectors Override Attribute Selectors

If you have HTML code like this:

with the following style rules:

You should be aware that the first will override the last, as you can see below.

These two styles are both targeting the ID of the element, but the first declaration does so using the ID selector (0100 points), whereas the second does so via an attribute selector (0010 points).

Inline Styles Have More Specificity

As we’ve mentioned, rules defined on the style attribute of the element itself have even more specificity as they are “closest” to the element that is to be styled. These kinds of styles override styles defined elsewhere.

The purple color in this case is out ranking both the red and green used in the previous example (1000 against 0100 and 0010).

!important Rule

You might be thinking, where does the !important rule fit in? The !important keyword is often used in a last-ditch attempt to win the CSS specificity wars when all else fails. Let’s see it in action by adding a new rule to the last example we have above.

Making our declarations look like this changes the whole game.

Without the !important rule, that last style stands no chance as (being an element selector) it ranks lowest.

It’s important to know that this rule has nothing to do with specificity, it’s simply overriding the other rules and its use is considered bad practice.

Universal Selectors

Universal selectors target anything on the whole page. Here is an example of a universal selector:

They can also be used as child selectors (eg: div * {}). These kinds of selectors have a specificity of 0000.

Conclusion

When next you have issues with conflicting styles, don’t pull your hair out! Calm your nerves, remember the hierarchy of specificity that starts with inline styles through IDsclasses, attributes and pseudo-class selectors to elements and pseudo-element selectors.

And when writing CSS remember that you should only be as specific as you need to be, and not more. By being overly-specific with your style rules you’ll make it more difficult to counter those styles in certain situations.

Learn More About CSS Specificity

There are tons of resources that you’ll find useful if you plan to dig deeper into CSS specificity. You can start with these:


No comments:

Post a Comment