Back to articles
October 7, 2024
Specificity in CSS
Have you ever wondered why your styles were not applied correctly when using external libraries like Material UI or even a simple native <button>
tag? You might have styled it with a specific background color, yet the changes didn’t take effect. This issue often boils down to how specificity is calculated in CSS. Below, I will explain how specificity works and provide some examples to demonstrate its behavior.
Let's start with a simple example. We have a button element with two classes:
<button class="red-color green-color">testing button specificity</button>
.red-color { background-color: red; } .green-color { background-color: green; }
In this example, the button will be green. Why? Because the .green-color
class is defined after red-color
in the stylesheet, meaning it has higher priority and thus overrides the previous style.
How can we change the button's color to red without modifying the order of CSS rules?
Here's one way:
button.red-color { background-color: red; } .green-color { background-color: green; }
Now, the button is red, but why?
This behavior results from CSS specificity. But what is specificity?
What is Specificity
Specificity in CSS is a rule that determines which styles are applied when multiple rules match the same element. It is a way for the browser to decide which CSS rule takes precedence when an element has multiple conflicting styles. The rule with the highest specificity will be applied, overriding any other rules with lower specificity.
Below are the different types of selectors, ranked from highest to lowest specificity:
- IDs (
#id
):1-0-0
- Classes (
.class
), attributes ([attr]
) and pseudo-classes (:hover
):0-1-0
- Element selectors (e.g.,
div
,p
) and pseudo-elements (::before
,::after
):0-0-1
Scoring Specificity
Let's go through the most important rule of specificity: scoring. Each selector type gives a specific number of points based on its type:
We start with a score of 0-0-0
. Here's how different selectors add to this score:
Selector | ID Selectors | Class Selectors | Element Selectors | Total Specificity |
---|---|---|---|---|
#id | 1 | 0 | 0 | 1-0-0 |
.class | 0 | 1 | 0 | 0-1-0 |
button | 0 | 0 | 1 | 0-0-1 |
button.class | 0 | 1 | 1 | 0-1-1 |
As you can see, each selector has a different scoring value. The higher the score, the higher the specificity.
Inline styles and !important
-
Inline styles: (e.g.,
style="color: red"
) have a specificity of1-0-0-0
, which is higher than any selector type mentioned above. -
!important: The
!important
flag is another special case that can override any other styles, even inline styles. For example:
red-color { background-color: red !important; } button.green-color { background-color: green; }
In this case, even though button.green-color
has higher specificity and is defined later, the red background will still be applied because of the !important
flag. However, using !important
should be used carefully and minimized, as it can make maintaining CSS very difficult.
Final Notes
Remember that the order of CSS rules in your stylesheet matters. If two selectors have the same specificity, the one defined later will take precedence. For example:
.red-color { background-color: red; } .green-color { background-color: green; }
Here, the button will be green because the .green-color
class is defined after .red-color
.
Summary
- CSS specificity helps determine which styles are applied to an element when multiple rules are present.
- Specificity is scored using a formula:
0-0-0-0
(Inline styles, IDs, Classes, Elements). - Inline styles and the
!important
flag can override specificity, but should be used sparingly. - The order of rules in your stylesheet matters if specificity scores are the same.
Understanding CSS specificity is crucial for debugging and ensuring that your styles are applied as expected. Make sure to experiment with different selectors and keep specificity in mind when writing your CSS rules!