CSS Specificity
Sometimes we may have rules that conflict with one another, and we end up with some unexpected results…
“But I wanted these paragraphs to be blue, why are they red like these other paragraphs?!”
As frustrating as this can be, it is important to understand that CSS doesn’t just do things against your wishes. CSS only does what we tell it to do. One exception to this is the default styles that are provided by a browser. These default styles vary from browser to browser, and they are why some elements create a large “gap” between themselves and other elements, or why buttons look the way they do, despite us not writing any CSS rules to style them that way.
So if you end up with some unexpected behavior like this, it is either because of these default styles, not understanding how a property works, or not understanding this little thing called the “cascade.”
The cascade is what determines which rules actually get applied to your HTML. There are different factors that the cascade uses to determine this. We will examine three of these factors, which will hopefully help you avoid those frustrating “I hate CSS” moments.
What is Specificity?
A CSS declaration that is more specific will take precedence over less specific ones. Specificity follows many rules:
- Inline styles, which you went over in a previous lesson, have the highest specificity compared to selectors.
- Each type of selector has its own specificity level that contributes to how specific a declaration is.
- Other selectors contribute to specificity, but you are focusing only on the ones you have gone over so far:
- ID selectors (most specific selector)
- Class selectors
- Type selectors
Specificity will only be taken into account when an element has multiple, conflicting declarations targeting it, sort of like a tie-breaker. An ID selector will always beat any number of class selectors, a class selector will always beat any number of type selectors, and a type selector will always beat any number of anything less specific than it.
When no declaration has a selector with a higher specificity, a larger amount of a single selector will beat a smaller amount of that same selector.
Examples
Let’s take a look at a few quick examples to visualize how specificity works. Consider the following HTML and CSS code:
<div class="main">
<div class="list subsection">What color am I?</div>
</div>
/* rule 1 */
.subsection {
color: blue;
}
/* rule 2 */
.main .list {
color: red;
}
In the example above, both rules are using only class selectors, but rule 2 is more specific because it is using more class selectors. Therefore, we see: What color am I?
Now, let’s change things a little bit:
<div class="main">
<div class="list" id="subsection">What color am I now?</div>
</div>
/* rule 1 */
#subsection {
color: blue;
}
/* rule 2 */
.main .list {
color: red;
}
In the example above, despite rule 2 having more selectors, rule 1 is more specific because ID beats class. Therefore, we see: What color am I now?
What if we apply the following CSS rules?
/* rule 1 */
#subsection .list {
background-color: yellow;
color: blue;
}
/* rule 2 */
#subsection .main .list {
color: red;
}
In this final example, both rules are using ID and class selectors, so neither rule is using a more specific selector than the other. The cascade then checks the amounts of each selector type. Both rules only have one ID selector, but rule 2 has more class selectors, so rule 2 has a higher specificity!
While the color: red
declaration would take precedence, the background-color: yellow
declaration would still be applied since there is no conflicting declaration for it.
Calculating Specificity
At this stage in your learning, don’t worry about calculating specificity. It’s a good idea to understand how specificity works, but it’s not something you will need to worry about regularly. The more you work with CSS, the more you will understand how specificity works, and the more you will be able to use it to your advantage.
Inheritance
Inheritance refers to certain CSS properties that, when applied to an element, are “inherited by” or “passed down to” that element’s descendants, even if we don’t explicitly write a rule for those descendants.
Typography based properties (color
, font-size
, font-family
, etc.) are usually inherited, while most other properties are not.
For exaample, the following HTML and CSS code would result in the child element having the same color
as the parent element, even though we didn’t explicitly write a rule for the child element:
<div class="parent">
<div class="child">
<p>This paragraph should be blue!</p>
</div>
</div>
.parent {
color: blue;
}
The exception to this is when directly targeting an element, as this always beats inheritance (due to specificity):
<div id="parent">
<div class="child"></div>
</div>
#parent {
color: blue;
}
.child {
color: red;
}
Despite the parent element having a higher specificity with an ID, the child element would have the color: red
style applied since that declaration directly targets it, while color: blue
from the parent is only inherited.
The Cascade
“Cascade” in CSS (cascading style sheets) refers to the order in which CSS rules are applied to an element. Specificity defines tht order in most cases, but sometimes the order is very literal.
For example, if we have the following CSS rules:
.text-red {
color: red;
}
.text-yellow {
color: yellow;
}
And the following HTML:
<p class="text-red">This text should be red!</p>
<p class="text-yellow">This text should be yellow!</p>
<p class="text-red text-yellow">This text is... what color?</p>
How does the cascade determine which rule to apply?
Really simply, actually. Whichever rule was the last defined is the winner.
For an element that has both the classes, the cascade would run through every other factor, including inheritance (none here) and specificity (neither rule is more specific than the other). Since the .text-yellow
rule was the last one defined, and no other factor was able to determine which rule to apply, it is the one that gets applied to the element.
Knowledge Check
What is the primary purpose of CSS specificity?
- Select an answer to view feedback.
Which of the following selectors has the highest specificity?
- Select an answer to view feedback.
Given the CSS selectors .main .list
and #subsection
, which one is more specific?
- Select an answer to view feedback.
Which of the following CSS properties is most likely to be inherited by descendant elements?
- Select an answer to view feedback.
If an HTML element has two classes, and the CSS rules for both classes have the exact same specificity, which rule will be applied?
- Select an answer to view feedback.