How to Count CSS Specificity Scores and Leverage !Important Overrides
If you are having difficulty getting a particular CSS style to “appear”, one thing to check is your specificity. CSS specificity is a four digit score for resolving cascade conflicts. You can actually add up the specificity score to determine which conflicting style should prevail. The four digit score is comprised of inline style, id, class, and element. You can express it as #, #, #, #. Examples are provided below.
For example, what gets displayed when you have two conflicting styles specified for the same element?
li { background-color: blue; }
li { background-color: yellow; }
Of course we know intuitively and through practice that the second style is displayed because it is read after the first and so it “overwrites” that first style. Less intuitively, you should know that the second wins because it has the same level of specificity as that first style. The two styles above each have the score 0, 0, 0, 1 because they are not inline styles, they have no id or class specification, and they specify only one element each.
Specificity refers to how specific you identify an element. Referring to just ‘li’ is just the single list item element, you are not referring to additional element information. This is like specifying different styles based on nesting, such as ‘div a’ vs. ‘p a’. Those could have two different styles because they have different nesting.
For another example, which style do you think will get displayed?
ul li { background-color: blue; }
li { background-color: yellow; }
The first style will win over the second because of greater element specificity, despite the potential of overwriting later in the script. The first style’s specificity score is 0, 0, 0, 2 while the second style’s score is still just 0, 0, 0, 1. That tiny extra specificity causes the first style to win out and get displayed. Now the power of specificity should be dawning on you, and why specificity can cause frustrating display problems in a large stylesheet. Let’s explore further.
Which style do you think will get displayed?
.nav li { background-color: blue; }
ul li { background-color: yellow; }
Of course the first style wins again because the class selector has greater specificity than the element selectors. The score is 0, 0, 1, 1, versus 0, 0, 0, 2.
Which style do you think will get displayed?
#nav li { background-color: blue; }
.nav ul li { background-color: yellow; }
Of course the first style wins again because the id selector has greater specificity than the class selector. The score is 0, 1, 0, 1, versus 0, 0, 1, 2.
Which style do you think will get displayed?
#nav .nav div ul li { background-color: yellow; }
...
<body>
<div id="nav"><ul><li style="background-color: blue;">Data</li></ul></div></body>
The inline style gets displayed here (though only on the elements containing the inline style) because inline styles have slightly higher specificity than id, class, or element styles specified in header styles or external stylesheets (remember ‘cascading’ is a key concept). The score is 1, 0, 0, 0 versus 0, 1, 1, 3. Although the specificity is greater here, you realize inline styles are an evil thing because you are mixing style with content. You should know the rule exists and how it works, and then pledge to never take it that far unless you are debugging code.
Speaking of debugging code, what if you specify something as much as you reasonably can, yet you cannot get it to display? Rather than dropping it into an inline style, you can use the !important keyword in your style, which functions as a kind of override function as far as specificity goes.
Which style do you think will get displayed?
#nav .nav div ul li { background-color: blue !important; }
#nav .nav div ul li { background-color: yellow; }
Of course the first style wins again because of the !important keyword (yes, it will also beat an inline style specification). This case indicates you have conflicting styles in your stylesheet and you need to check specificity to target what is conflicting. If your style does not display when you use !important, it indicates you have another problem like misspelling an element, class, or id.
After you have fixed the conflict, go back and remove the !important keyword or you will forever be chasing your tail across stylesheets with more and more !important declarations. Use !important only for debugging purposes.
Finally, remember specificity only comes into play when styles conflict. You can have dozens of separate style statements work beautifully together so long as they are specifying different style elements (such as background-color, font-style, color, padding, etc.) It is only when they specify the same style elements with conflicting values does the specificity score become important.










