Specificity in CSS is an algorithm used by browsers to read styles from most relevant to least important selectors (left to right).
The weight of selectors
There are 3 main categories of selectors in the CSS Specificity. The first and most important of them is the ID. The second one is CLASS and the last is the TYPE selector. Combining this into one chain we have ID-CLASS-TYPE.
As e helper for specificity we can create some kind of software or application versioning. Everyone is familiar with software versions like 0.0.1 or 1.0.0. We will get back to this versioning in just a moment.
id selector
Adds 1.0.0 to the weight value. The most important selector.
class selector
Adds 0.1.0 to the weight value to every class, attribute or pseudo class selector. It includes selectors such as:
.container, [type="text"] :hover, :nth-of-type(3n), :required
tag/type selector
Adds 0.0.1 to the weight value. It includes all tag selectors such as p, h1, div, span and also pseudo-elements like:
::before ::after ::placeholder
Combinators
Combinators such as >, ~, + don’t add any value to the specificity. They have 0.0.0. weight.
Specificity calculator in the example
Above we have listed all weights that we need. Now we can create simple HTML and add some styles with specificity comments.
<!-- --> <div class="wrapper"> <div class="container one">1</div> <div class="container two middle" id="two">2</div> <div class="container three">3</div> </div> <!-- -->
Simple HTML code. One wrapper that has 3 children. Every child has at least two classes but the one in the middle has additional class and also an id attribute. Specificity syntax below.
Specificity id class tag/type 0 0 0 0.0.0
/* */ .wrapper { display: flex; gap: 1rem; color: white; font-size: 1.5rem; } /* CASE 1 */ .wrapper div { /* 0.1.1 */ width: 100px; height: 100px; background-color: black; } /* CASE 2 */ .wrapper .two { /* 0.2.0 */ background-color: yellow; } /* CASE 3 */ .wrapper .two.middle { /* 0.3.0 */ background-color: blue; } /* CASE 4 */ #two { /* 1.0.0 */ background-color: red; } /* CASE 5 */ #two.middle { /* 1.1.0 */ background-color: green; } /* CASE 6 */ div#two.middle { /* 1.1.1 */ background-color: pink; } /* CASE 7 */ .wrapper div#two.middle { /* 1.2.1 */ background-color: gray; } /* CASE 8 */ .wrapper div#two.middle.container { /* 1.3.1 */ background-color: purple; } /* */
Code explanation
Case 1 – parent class (0.1.0) selector and tag (0.0.1) selector = 0.1.1 overwritten
Case 2 – parent class (0.1.0) selector and class (0.1.0) selector = 0.2.0 overwritten again
Case 3 – parent class (0.1.0) selector, and two times class (0.2.0) selector = 0.3.0 overwritten again
Case 4 – id (1.0.0) selector = 1.0.0 overwritten again
Case 5 – id (1.0.0) selector and class (0.1.0) selector = 1.1.0 overwritten again
Case 6 – tag (0.0.1) selector and id (1.0.0) and class (0.1.0) selector = 1.1.1 overwritten again
Case 7 – parent class (0.1.0) selector and tag (0.0.1) selector and id (1.0.0) selector and class (0.1.0) selector = 1.2.1 overwritten again
Case 8 – parent class (0.1.0) selector, id (1.0.0) selector and two times class (0.2.0) selector = 1.3.1 overwritten again
In the end, thanks to the CSS specificity, we should end up with a purple background color value for the middle div.
Summary
A good understanding of specificity in CSS will pave the way for you to write better, more thoughtful styles. This will reduce the chance of !important being used, as using appropriate combinations of !important selectors will no longer be needed in some cases.