How Does CSS Specificity Decide Which Styles to Apply

How does CSS specificity decide which styles to apply?

It's based on IDs, classes and tags. IDs have the highest specificity, then classes then tags, so:

.item a     == 0 1 1      0 (id) 1 (class=item) 1 (tag=a)
.special == 0 1 0
#foo == 1 0 0
#foo .bar a == 1 1 1
#foo #bar == 2 0 0

whichever has the most wins :) If it's a tie, whichever one comes last in the document wins. Note that 1 0 0 beats 0 1000 1000

If you want .special to apply, make it more specific: .item a.special

What is the order of precedence for CSS?

There are several rules ( applied in this order ) :

  1. inline css ( html style attribute ) overrides css rules in style tag and css file
  2. a more specific selector takes precedence over a less specific one
  3. rules that appear later in the code override earlier rules if both have the same specificity.
  4. A css rule with !important always takes precedence.

In your case its rule 3 that applies.

Specificity for single selectors from highest to lowest:

  • ids (example: #main selects <div id="main">)
  • classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
  • elements (ex.: div) and pseudo-elements (ex.: ::before)

To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.

Example: compare #nav ul li a:hover to #nav ul li.active a::after

  • count the number of id selectors: there is one for each (#nav)
  • count the number of class selectors: there is one for each (:hover and .active)
  • count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.

A good article about css selector specificity.

Understanding specificity: achieving desired selector outcomes without using !important

A class has a specificity of 10. An element has a specificity of 1.

Therefore, in the first instance:

  • the .main li a selector has a specificity of 12.
  • the .active a selector has a specificity of 11

Because they both target the same element, and the former has a higher specificity, the latter loses the battle to style the element.

In the second instance:

  • the .primary p selector has a specificity of 11.
  • the .copyright selector has a specificity of 10.

Again, because they both target the same element, and the former has a higher specificity, the latter loses the battle to style the element.

The !important annotation trumps all specificity. Hence, with that applied, .active a and .copyright re-take the elements.

If you want to remove !important, which would be the right thing to do as it's not necessary here, you can instead boost the specificity of the selectors.

An ID has a specificity of 100. So that can quickly move a selector up in priority.

Here are some examples:

.main li a      { color: #7ab2c1; }  /* previous winner; specificity 12 */.main .active a { color: #ff0000; }  /* added class selector; specificity now 21 */.primary p      { font-size: 12px; } /* previous winner; specificity 11 */#copyright      { font-size: 8px;} /* switched to ID selector; specificity now 100 */
<nav class="main">  <ul class="group">    <li class="active"><a href="#">Home</a></li>    <li><a href="#">About</a></li>    <li><a href="#">Contact</a></li>  </ul></nav><footer class="primary">  <p><a href="#">Sign up</a> for our newsletter, it's a racket!</p>  <p id="copyright">Copyright © Sven's Snowshoe Emporium.                    All Rights Reserved.</p></footer>

css specificity when DOM element has multiple classes

It's a little difficult to determine what you're actually asking here. A specific example would help.

But in general the order of style precedence from highest to lowest is by:

  1. Inline styles
  2. Included styles (same document)
  3. Externally referenced styles

Within all of those, the style that's listed last has higher precedence, assuming the specificity is the same. However, a style that's at a higher precedence level (such as an inline style) will always overwrite the others regardless of specificity. So, an inline style on an element will always overwrite the styles in the included style sheet.

Here's more info, which you may already know about specificity... http://www.htmldog.com/guides/cssadvanced/specificity/

The actual specificity of a group of
nested selectors takes some
calculating. Basically, you give every
id selector ("#whatever") a value of
100, every class selector
(".whatever") a value of 10 and every
HTML selector ("whatever") a value of
1. Then you add them all up and hey presto, you have the specificity
value.

This all having been said, !important adds another layer where the same rules apply, just !important is given precedence over all non-!important styles.

UPDATE:
Your example is a bit curious, and I think you're misunderstanding specificity. Specificity does not mean that a class that applies to the same element as another class wholly overwrites it. What it means instead is that "If there's style attributes that are the same, the one with the higher specificity overwrites the others."

In your example, an attribute on cls2 that matches any of the other class styles will overwrite them. However, if there's no style conflicts, there's no problem! It'll just take all of the styles.

Perhaps it'll help to think of it like assigning variable on any old object. There's multiple ways to reference the variable, but your specificity defines your execution order. The assignment that sets the variable last is what it is when the object actually gets rendered.

Order of prioritization when using multiple contradictory css files

Quick Answer:

If both pieces of CSS have the same specificity (for example, they're both body{), then whichever gets called LAST will override the previous one.

BUT, if something has higher specificity (a more specific selector), it will be used regardless of the order.


Example 1:

<div class="container">
<div class="name">Dave</div>
</div>

<style>
.name { color: blue; }
.name { color: red; }
</style>

The above example will make the color red. Both selectors are the same, and therefore also have the same specificity. And because CSS reads top-to-bottom, we first tell it to be blue, but then we override that by telling it "nevermind, make it red".


Example 2:

<div class="container">
<div class="name">Dave</div>
</div>

<style>
#container .name { background-color: blue; }
.name { background-color: red; }
</style>

The above example will make the background color blue, even though blue was first because the selector is more "specific".


Exception (the use of !important):

The inclusion of !important will override both specificity and order, but in my opinion, should only be used if you're trying to mess with a third party code in which you don't have access to change it any other way.


External CSS:

Overwrite rules work the same on external CSS files. Just imagine putting them first-to-last, top-to-bottom. The selectors called in the first file(s) will get overwritten by same-specificity-selectors in any subsequent files. But specificity will still trump order within the same file or in multiple files.


How to test:

In Chrome, Firefox, and modern versions of IE (probably Safari too), you can right click on something and click "Inspect Element". This will show you the HTML as well as any applied CSS. As you scroll down the CSS (usually on the right), you'll see things that are crossed out - that means they're either incorrect CSS or have been overwritten. To test, you can modify the CSS selectors (either in your own code or right there in the developer tools box) to make them more specific and see if that makes then un-crossed out...etc. Play around w/ that tool - it's VERY helpful.

Not sure how "specific" something is?
Try some of the many online CSS specificity tools:

  • https://polypane.app/css-specificity-calculator
  • https://specificity.keegan.st/
  • https://www.codecaptain.io/tools/css-specificity-calculator

CSS specificity testing

The method I settled with is to use getComputedStyle to get the style with "highest priority". In the css I add a "tag" to the content property. In jasmine I then check if the desired tag is the computedStyle. (I will extend this in scss so that the content property is set by a mixin if test mode is used and not set in production.) This only makes a unit test for the class of highest priority, but not for the second highest etc.

Below is a tests to illustrate the example (only the first and last should pass).

// specs codedescribe("CSS", function() {  it("Div element of class test should be handled by .test", () => {    const testdiv = document.getElementById("testdiv")    m = window.getComputedStyle(testdiv).getPropertyValue("content");        expect(m).toEqual('".test"');  });
it("Div element of class test should be handled by div", () => { const testdiv = document.getElementById("testdiv") m = window.getComputedStyle(testdiv).getPropertyValue("content"); expect(m).toEqual('"div"'); });
it("Div element should be handled by .test", () => { const testdiv = document.getElementById("testdiv2") m = window.getComputedStyle(testdiv).getPropertyValue("content"); expect(m).toEqual('".test"'); });
it("Div element of class test should be handled by div", () => { const testdiv = document.getElementById("testdiv2") m = window.getComputedStyle(testdiv).getPropertyValue("content"); expect(m).toEqual('"div"'); });
});

// load jasmine htmlReporter(function() { var env = jasmine.getEnv(); env.addReporter(new jasmine.HtmlReporter()); env.execute();}());
.test {    content: '.test';}
div { content: 'div';}
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script><script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script><link href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/><div class="test" id="testdiv">TestDiv</div><div id="testdiv2">TestDiv</div>

Specificity and Direct Targeting

I'm losing scope of where specificity comes into practice

Specificity matters when two or more competing selectors are applying styles to the same element(s) - the rule with the higher specificity wins.

Specificity does not matter when evaluating styles that are being applied to different elements, even if that style is inherited from an ancestor.

Is it correct to say, before applying specificity rules and calculating specificity, if the element is directly targeted, specificity rules do not apply and the direct target always takes precedence

No, I would say that is incorrect. I wouldn't get wrapped up in the phrase "directly targeted"... in a sense all CSS selectors are directly targeting a set of elements, yet some properties of that rule-set can cascade to descendants, like color. Inherited styles do not also inherit the specificity from the rule-set they originated from; otherwise, to change the color of a child element you'd have to match or beat the specificity every time.

For example, the text in the following snippet is red because #main (the selector) has a higher specificity than div (the selector) and the styles are applied to the same element: