What is CSS Specificity?

Tram Ho

Opening

Hello everyone, today I will continue the series on basic CSS. This article, as the title has specified, I will introduce and analyze Specificity in CSS. This is the most important part of knowledge (not the most, second) but not too complicated, I will try to present simple things that we often use every day. If you see any errors or feedback, please let me know in the comment below.

Question

In an interview when I was a mid-level developer, I was asked a high theoretical fundamental question, but I couldn’t answer it, I would like to write it down here (not completely accurate but the nature of the question ask constant)

In your opinion, will the h1 tag be green or purple ? The answer is purple , you can confirm the results yourself. The explanation for this problem is at the end of the article.

I did not answer this question, but at that time I thought that the interviewer was just asking a puzzle question, but in fact who wrote CSS like that. And later I realized, it is not a puzzle question, but it is part of an extremely important knowledge array of CSS, which is CSS Specificity that any frontend developer needs. understand and master. If you don’t understand or know about it, ask yourself if you are writing CSS emotionally, or in a daily routine.

Ok so let’s find out what CSS Specificity is.

What is CSS Specificity?

Let’s take a simple example below to describe the definition below:

Oh man, only a span card but there are 3 selectors trying to “fight” to change its color, like a fight. But the good news is that this war will always have a winner, thanks to the referee being the browser. However, how does the browser determine the winner? The answer is thanks to a set of rules, and the browser relies on this set of rules to determine who wins. CSS Specificity is an essential part of the “rule set”.

I will define it as simply as follows:

Specificity is the weight the browser relies on to determine what is the css style of an element.

Weighting is as simple as 2> 1 for 2 wins, or 3> 2 for 3 wins, that’s all. One thing is equally important: Specificity is the weighting of the CSS selectors. More simply, the browser will try to determine which selector is the most specific (most specific) and style according to that selector.

Is this “rule set” complicated? Is specifying Specificity complex? If the browser uses it, it must be complicated? The answer is it’s not complicated and developers can still memorize it easily. In other words, 80% of the rules are very simple and easy to understand, can be memorized, and the other 20% of the rules will be quite confusing that we rarely use in practice, so we don’t need to. have to remember it, let the browser do its thing.

Why should developers memorize this set of rules (80% of the rules are commonly used)? This is not an issue, if you are a frontend developer who specializes in handling layout and CSS, this is a knowledge that you should keep in mind, not just for reading. However, I don’t want you to know it mechanically, but to understand it. And when you understand, you will remember it yourself, or when you forget it, you just need to read it a bit to remember.

How to define Specificity weight and how to compare

The way to determine the weight of the CSS selectors is simply to play a game of counting numbers and filling in the 3 boxes below.

GrabCV - CSS Specificity

https://css-tricks.com/specifics-on-css-specificity/

In the first cell (ID), I will count how many id selector has. For example #parent { } is 1, #parent #child { } is 2. After counting, fill in the blanks.GrabCV - CSS Specificity

In the second cell, I will count how many classes in total (eg .list ), psuedo-class (eg :hover ) and attribute (eg [type=radio] ).

GrabCV - CSS Specificity

In the third cell, I will count how many types of selectors (eg h1 ), and pseudo-element (eg ::before ) are total.

GrabCV - CSS Specificity

We have basically finished the weight determination, now let’s compare them. The comparison is extremely simple, like grade 1 math:

  • 1,1,0 greater 1,0,0 (110> 100)
  • 0,1,0 greater than 0,0,1 (10> 1)
  • 1,3,0 greater than 1,0,3 (130> 103)
  • 0,0,1 equal to 0,0,1 (1 === 1)

Oh, what if they’re equal? If they are equal, whoever is declared eventually wins. This I will repeat in the next part. Now let’s practice counting weights through the following examples:

  • #parent : 1,0,0
  • #parent #child : 2,0,0
  • [id="parent"] : 0,1,0
  • li : 0,0,1
  • ul > li : 0,0,2
  • ul ol + li : 0,0,3
  • h1 + *[rel=up] : 0,1,1
  • ul ol li.red : 0,1,3
  • li.red.level : 0,2,1
  • li.name::before : 0,1,2
  • #parent:not(ul) : 1,0,1
  • .foo:is(.bar, #bar) : 1,1,0

Some other rules

There are a few other rules that more or less affect the Specificity weights that you cannot ignore:

  • Universal selector * will be ignored when determining the weight. For example the * selector * would have a weight of 0.0,0. Or *.foo will have a weight of 0,1,0. This means that *.foo and .foo are exactly the same.
  • Combinators like + , > , ~ , || or space cũng sẽ được bỏ qua khi xác định trọng số. Ví dụ .parent .child.parent > .child có cùng trọng số là 0,2,0.
  • :not() not considered a pseudo-class, so it is omitted when calculating the weights. However, the weight will still be calculated with the param passed to it. For example: div:not(.parent) p will have a weight of 0,1,2.
  • :is() is similar to :not() , but since we could pass in a selector list, the weight will be calculated with the matched selector with the highest weight. For example: div:is(.parent, #foo) will have a weight that can be both 0.1,1, it can be 1.0,1, and it can be 1,1,1, depending on the situation. How many cases does it match. It’s also very complicated, isn’t it.
  • “Inline styles” will always have the highest weight, defeating all opponents (except for the last boss !important ). In the example below, even if you try to write external CSS to change its color, it is useless (of course as I said, you can still use !important ):

  • Our ultimate boss !important can beat every opponent, even inline style which is already extremely powerful. You see the example just above is clear. But what if the last 2 bosses fight? The answer is in the rule below. For example:

  • When 2 or more selectors have the same weight, the last declared selector wins. In the showdown on the rule above, blue is the winner. Of course if we swap these 2 selector positions, the green is the winner. This is a common error when we are not very knowledgeable about Specificity (usually junior friends), accidentally changing the position or modifying CSS innocently alters the weight, leading to an unexpected style error.

Does proximity / proximity affect?

Actually I don’t know how to translate the word “proximity” properly, but the meaning of it can be understood through the example at the beginning of the article.

“Proximity” implies that the h1 tag is closer to body than html , so does body h1 selector have more weight than html h1 ? The answer is NO .

In this case, since both have the same weight of 0,0,2, we will use the rule “whoever is declared eventually wins”. The result will be the winning html h1 , the color of the h1 tag will be purple .

Note & ponder

  • Is a selector with great weight good? The example below, with a weight of 2,3,4, will be very difficult to override, and will make your code confusing and difficult to maintain or extend:

  • Whenever you are in a situation where you don’t understand why your element has unexpected style, Specificity will help you. However, instead of counting the weights by hand, now with the powerful browser devtools, determining style errors is extremely simple. However, these tools also build on CSS Specificity principles, there is no difference.
  • Specificity only makes sense if an element has multiple selectors pointing to it. Strictly speaking, if there is only one participant in the war, then obviously that person will win.
  • In CSS there is the inheritance of styles from parent elements. However, this inheritance will always come after the selectors that point to the element. You pay attention when using devtools to see only.
  • Whether or not to use inline styles is still a matter of controversy. Some linters will warn if you write inline styles, but you can still turn the warning off if you want. One of the reasons is that because its weight is too high, it will easily cause unexpected errors, or it will be difficult to override and force !important . Another reason is that for many “experts”, the CSS should be placed in .css files for easy management, but if it is in style (html), then all the confusion?
  • Although the !important final boss is extremely powerful, using !important not a good solution and should be limited to use, like the inline styles I have just mentioned. Before you have to resort to !important , let’s think carefully whether we can use CSS Specificity to achieve our goals.

BEM & ITCSS

Here I don’t have to explain or introduce in detail these 2 “methods”, but just want to point out a few points related to Specificity. In addition to BEM and ITCSS there are many other methods, but they are all based on Specificity.

BEM : By default, you already know BEM , some of its principles can be mentioned such as:

  • Avoid using id ( #foo ): the reason as I shared, id has a great weight and is quite difficult to override, so trying to override it will easily push your CSS to a not so bright future.
  • Avoid nested selectors, try to flatten selectors: for the same reason, nested selector also increases selector weight. The BEM example would encourage:

ITCSS : also a thorough application of CSS Specificity rules, making your CSS easy to scale, extend and maintain (SEM). ITCSS has a lot of things to say but it is outside the scope of the article so I would like to stop here, if you are interested, leave a comment for me to make a separate article about it.

CSS Specificity calculator

Just search google and you will see a few tools that will help you determine the weight of the selector:

https://polypane.app/css-specificity-calculator/
https://www.codecaptain.io/tools/css-specificity-calculator
https://isellsoap.github.io/specificity-visualizer/

However, you should not completely believe it because these tools only count the weights in simple cases, but in more complicated cases, it can still be wrong.

I close my post with a funny but pretty famous photo.

GrabCV - What is CSS Specificity

https://specifishity.com/

Epilogue

Basic CSS is really not much, you just need to know enough to be able to roam around. Since it is not much and it is not difficult, you should take the time to learn and master it. Before I went to the frontend interview, I saw quite a few companies interviewing CSS, perhaps they assumed that the frontend developer had to know CSS, or they themselves didn’t like CSS so they didn’t want to ask questions. But if you accidentally get asked, then please “slap with” interviewer.

As always, if you find something missing or wrong in the article, please leave a comment for me to change. If you find the article useful and useful, upvote or comment so that you will be motivated to write next articles.

Share the news now

Source : Viblo