Understanding CSS selector priority / specificity
I'll just toss in a link to the CSS 2.1 spec itself, and how browsers are supposed to calculate specificity:
CSS 2.1 Section 6.4.3:
A selector's specificity is calculated as follows:
- count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
- count the number of ID attributes in the selector (= b)
- count the number of other attributes and pseudo-classes in the selector (= c)
- count the number of element names and pseudo-elements in the selector (= d)
- The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
If the specificities are equal, then CSS 2.1 Section 6.4.1 comes into play:
- Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.
Note that this is talking about when the style is defined, not when it is used. If classes .a
and .b
have equal specificity, whichever is defined last in the stylesheet(s) wins. <p class="a b">...</p>
and <p class="b a">...</p>
will be styled identically, based on the definition order of .a
and .b
.
What are the priorities among CSS selectors
The gory details in the spec are actually reasonably readable. In summary:
!important
rules and inlinestyle
rules win most.Otherwise, normally the more specific wins.
#id
is a more specific selector than.classname
is a more specific selector thantagname
.Where rules are equally specific, the one declared last wins.
There is no particular reason why this ‘shouldn't happen’. It's normal to specify a broad-brush rule and then add a more specific rule to target one case; multiple same-property rules on a single element are not unusual or undesirable.
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>
Why do I have to use the !important in this case?
Be more specific with your css and remove all your !important
s:
.parent div.child {
width: 50%;
height: 50px;
}
should work just fine
Am I correct in my understanding of selectors?
It's because classes have higher specificity value than Elements and Pseudo Elements. In your case .top-menu
have higher specificity than the element ul
, therefore its style is followed/used. Refer to this table for specificity:
More on specificity here.
Specificity order of CSS tag selectors with equal specificity
Specificity matters when two or more selectors are matching the same element – not the case here.
e.g.:
in the example below the more specific selector div#id.class
won't win against h1
because they are referring to two distinct elements, so the color of h1
is determined by the first rule
h1{ color: blue;}
div#id.class { color: red;}
<html><head></head><body> <div id="id" class="class"> <h1>This is the title</h1> </div></body></html>
Which of the following two selectors has a higher CSS specificity?
You can't hover over a ::first-letter
, however, all things being equal, the first selector is stronger:
/* Selector 1 -> #object h2::first-letter */#this h2::first-letter{ color: red}
/* Selector 2 -> body .item div h2::first-letter:hover */body .item div h2::first-letter{ color: blue;}
<div class="item"> <div id="this"> <h2>This is a title</h2> </div></div>
What is the order of precedence for CSS?
There are several rules ( applied in this order ) :
- inline css ( html style attribute ) overrides css rules in style tag and css file
- a more specific selector takes precedence over a less specific one
- rules that appear later in the code override earlier rules if both have the same specificity.
- 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.
Related Topics
Whatsapp Use Only HTML to Share Url Link by a Descriptive Text
Why Am I Seeing a 404 (Not Found) Error Failed to Load Favicon.Ico When Not Using This
How to Avoid Page Break Inside Table Row for Wkhtmltopdf
Make Container Shrink-To-Fit Child Elements as They Wrap
Angular 8 Material Dialog Close Button With X Top Right
How to Remove the Space Between Inline/Inline-Block Elements
Why Don't Flex Items Shrink Past Content Size
How to Vertically Align Elements in a Div
How to Center Text (Horizontally and Vertically) Inside a Div Block
Make a Div Fill the Height of the Remaining Screen Space
Print Page Numbers on Pages When Printing HTML
Want to Make Font Awesome Icons Clickable
Moving an Image Across a HTML Canvas
How to Stop Background from Jumping to the Top on Modal Toggle
Css - How to Have Swiper Slider Arrows Outside of Slider That Takes Up 12 Column Row
How to Add Some Non-Standard Font to a Website
How to Make All Images of Different Height and Width the Same Via CSS