Product Design Lessons

Intro to Foundation  |   Lesson #100

What Specifically is CSS Specificity

Selector Specificity and how CSS rules fight with each other.

CSS specificity is a crucial topic when developing websites and apps. No one likes writing CSS only to see that it didn't do anything. And then waste more time finding what CSS selector is overriding your changes. It could be a great pain in the butt. Specificity is how CSS rules fight with each other. MDN defines Specificity as "The specificity is a weight that is applied to a given CSS declaration based on the count of each selector type." In this lesson, we’ll learn how CSS specificity works, what selectors win over others, and some tips to stay out of trouble when writing CSS.

Who Wins?

In CSS, specificity is all about who would win in a fight. Selectors have a "power level" of sorts. When two selectors have the same CSS, the more powerful selector wins.

Selector specificity from most to least powerful:

  • Inline styles
  • IDs
  • Classes, attributes, and pseudo-selectors
  • Tags

The best way to illustrate this is to look at some examples and see who comes out the winner.

#rule-one {
  border-width: 3px;
}

.rule-two {
  border: 1px solid black;
}

.rule-three.rule-four {
  border: 
}
                              
                            

If you guessed it was the ID, you are right. Specificity is determined by these three rules:

  • Where the rule is written
  • The selector used
  • If the rule is !important

Let's break this down further.

1. Where the Rule is Written

The cascade is how styles written in different places interact. From most to least powerful, here's the pecking order for styles:

  • On the tag itself (using the style attribute)
  • In a tag
  • In an external stylesheet
<!-- On the tag itself -->
<h1 style="color: red;">Header!</h1>

<!-- In a <style> tag -->
<style>
  h1 {
    color: blue;
  }
</style>

<!-- In an external stylesheet -->
<link rel="stylesheet" href="assets/css/style.css">                    
                            

In practice, you won't encounter this much, because you will likely write code in an external style sheet.

2. The selector used

The type of selector plays the biggest role in specificity.

From most to least powerful:

  • Inline styles
  • IDs
  • Classes, attributes, and pseudo-selectors
  • Tags

A class beats a tag.

.header {
  color: red;
}

h1 {
  color: black;
}
                            

An ID beats a class.

#header {
  color: blue;
}

.header {
  color: red;
}       
                            

An inline style beats everything.

<h1 id="header" style="color: pink">Header</h1>

#header {
  color: blue;
}
                            

Two classes will beat one.

.button {
  background: gray;
}

.alert.button {
  background: red;
}    
                            

Nesting and chaining both count as "two classes". So it doesn't matter how the selectors are arranged, just how many there are.

/* These selectors have equal weight. */
.menu .button {}
.button.alert {}
                            

If two selectors have equal power, the last one wins. In this case .giant wins.

<a class="giant button">Click me!</a>

.button {
  font-size: 1rem;
}

.giant {
  font-size: 5rem;
}    
                            

Media queries don't add specificity, but remember that they aren't active unless the user's device matches the media query.

.header {
  font-size: 1rem;
}

@media screen and (min-width: 500px) {
  .header {
    font-size: 2rem;
  }
}
                            

3. Using !important?

How about don't? Good arguments can made to use !important as a specificity debugging tool. Otherwise, avoid using it as it will override other selectors even if it has higher specificity.

Hot Tips for Specificity

Avoid using tag selectors, because they're very generic. It's easy for styles defined for tags to "leak" into areas you don't expect.

/* Nope */
.thing span {

}

/* Better */
.thing-span {

}
                            

Use the least specific selector for the job.

/* Nope */
h1.header {

}

/* Better */
.header {

}
                            

Put more generic styles at the top of your stylesheet, and allow more complex components to override those styles farther down.

// These are generic styles 
that will apply to many elements
@import 'global';
@import 'layout';
@import 'typography';

// These are specific styles that 
will override the above CSS in spots
@import 'button';
@import 'tabs';
@import 'forms';
@import 'navigation';
                            

Testing Specificity

Is your CSS just not working for some reason? Use your browser's web inspector to check for specificity.

Every selector that applies to an element is displayed in order of power. The most powerful rules are at the top.

If a rule is being overridden, it will be crossed out.

Uncheck the box next to a rule to temporarily "erase" it.


Next Steps

Most people don’t like conflicts. Understanding CSS specificity will surely save you time and keep you from fighting with your styles. And now, we’ll leave you with some handy and fun resources:

MDN Specifity

Star Wars Specificty Chart

CSS Specificity with icons inspired by "The Shining"

About the instructor

rafi

Rafi Benkual oversees the Foundation Forum. Rafi managed people, stores and small organizations before joining ZURB as our Foundation Advocate.