Which of the following has a higher specificity in CSS? [duplicate] - css

This question already has answers here:
How are the points in CSS specificity calculated
(7 answers)
Closed 7 years ago.
I am learning the specificity of CSS selectors and come across the following examples. I could not figure it out, which CSS selector has higher specificity on another?
1. Example:
p#largetext
body p#largetex
2. Example:
p.largetext ul li
p ul li a
How the specificity of CSS works one over another? Why one is higher and one is lower?

Your question is answered by the CSS3 selectors, W3C Recommendation:
9. Calculating a selector's specificity
A selector's specificity is calculated as follows:
count the number of ID selectors in the selector (= a)
count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
count the number of type selectors and pseudo-elements in the selector (= c)
ignore the universal selector
Selectors inside the negation pseudo-class are counted like any other,
but the negation itself does not count as a pseudo-class.
Concatenating the three numbers a-b-c (in a number system with a large
base) gives the specificity.
With your examples we have:
1) p#largetext has a specificity of 1,0,1 (1 id, 1 type)
body p#largetex has a specificity of 1,0,2 (1 id, 2 types)
2) p.largetext ul li has a specificity of 0,1,3 (1 class, 3 types)
p ul li a has a specificity of 0,0,4 (4 types)
To obtain the value of the specificity you have to concatenate the 3 numbers. So for example 1, the second selector is more specific 102>101 and for example 2, the first selector is more specific 13>4.

In your first example, the second line would take priority over the first since it's more specific. Your second example is actually targeting two different elements, so depending on what you wanted, it would do two different things. If two rules share the same priority, then it would depend on the ordering of the rules themselves.
You can view a complete breakdown on MDN: Specificity - CSS | MDN

The specificity is a weight calculated based on the selector. Below is the list from the more specific to the less specific elements.
!important
inline declaration
ID selectors
Class selector, attribute selectors eg:[name="email"], or pseudo-clases eg: (:hover)
Type selector eg: div, h2, img
If the specificity of two selectors is the same, the latets rule will be applied.

Related

How do I select the nth class iteration from the DOM tree? [duplicate]

This question already has answers here:
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Matching the first/nth element of a certain type in the entire document
(1 answer)
Closed 4 years ago.
I'm looking for an nth-of-type descendant selector.
I have a class .class-name present a total of 7 times in my DOM tree.
How do I select the 3rd iteration or 4th iteration of the said class?
(the said class has different elements as parents (with different classes applied to them)
I tried this code and it doesn't work:
(because nth-of-type refers to the direct parent and I want it to work for the BODY element, which is an ancestor)
.class-name:nth-of-type(3) {margin-top: -215px;}
.class-name:nth-of-type(4) {margin-top: 34px;}
.class-name:nth-of-type(5) {margin-top: -115px;}
.class-name:nth-of-type(6) {margin-top: 455px;}
.class-name:nth-of-type(7) {margin-top: 545px;}
(The whole reason for using the said class was to be able to select the N-th iteration of it throughout the DOM tree, to avoid the hastle of targeting each ancestor using more complicated selector rules)
P.S. This is a more clear example than the issue posted here (Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?).
It's related, but not a duplicate.

CSS difference bwteen Pseudo-classes and Pseudo-elements in specificity calculation ?

I learned how to calculate css specificity based on http://reference.sitepoint.com/css/specificity
However, based on this reference, I don't understand what is the difference between Pseudo-classes (from c) and Pseudo-elements (from d)?
For example,
input[type="text"]:hover
hover is Pseudo-classes (from c) or Pseudo-elements (from d)?
compared with input[type="text"].error, which one has a higher specificity?
Pseudo classes (c) have a specificity of 10
Pseudo elements (d) has a specificity of 1
Both
input[type="text"]:hover and
input[type="text"].error
have a specificity of 21
input (element - 'd') = 1
[type="text"] (attribute - 'c') = 10
:hover (pseudo class - 'c') = 10
.error (class - 'c') = 10
There are also online specificity calculators available, such as this one.
The page cited says the same as CSS specifications such as CSS3 Selectors, section 9. Calculating a selector's specificity, though in less detail and non-authoritatively. The key point is that in specificity, pseudo-class selectors are treated like class selectors and pseudo-element selectors like type selectors (tag names). This means that a pseudo-class selector is more specific than a pseudo-element selector. The idea behind this is that classes (and pseudo-classes) refer to elements in a more specific way, like “Cadillac” (a class of cars, so to say) is more specific than “car” (a type of things, so to say).
Regarding :hover, whar matters is how it is specified in CSS specs. It so happens that it is a pseudo-class selector. This is natural, since it refers to an element that is in a specific state, so it can be characterized as a “dynamic class”.
Thus, input[type="text"]:hover and input[type="text"].error have equal specificity.

Efficient Algorithm To Compare Specificity Of CSS Rules

I was wondering what an efficient algorithm would be in the following scenario:
Given a parsed set of css rules, eg.
p.pStyle{margin-bottom:20px;font-family:Arial;}
p{font-family:Verdana;}
p.anotherPStyle{margin-bottom:10px;}
from a css stylesheet, it is possible that several rule sets apply to a given element (say a <p class="pStyle anotherPStyle">hello</p> in my document).
I need to determine what rules in the stylesheet apply to a given element firstly (so here that is p, pStyle and anotherPStyle), and then create a Comparator that is able to sort the applicable rules by specificity (from most-specific to most-general). NOTE: I already have designed an algorithm to apply the rules once sorted so you needn't solve that problem efficiently.
I've been toying with several ideas, namely one that involves determining the level in the DOM tree that a given rule is specific to....Though I'm not sure if this is the correct way to go?
How does the browser engine do this efficiently? I'm looking to replicate it in Java, but am comfortable with many other languages so any code you can offer is most appreciated.
Thanks
That is determined by specificity. In this case, since they are both equally specific, the declaration that comes last in the file, wins.
Specificity Calculation
Specificity is calculated by ranking the different parts of the selector.
Ranked from most specific to least:
Style attribute - If the rule is found in a style attribute, this rank gets 1.
ID - For each ID found in the selector, this rank gets an additional 1.
Classes, Pseudo-Classes, Attribute selectors - For each one found in the selector, this rank gets an additional 1.
Elements - For each element found in the selector, this rank gets an additional 1.
Where rank n > rank n+1, regardless of how many points each rank has.
Example
ul#nav li.active a
The points are:
0 - Not a style attribute.
1 - 1 ID found.
1 - 1 Classname found.
3 - 3 Elements found.
Therefore, each property in that selector has a specificity value of [0,0,1,1,3] (We'll get to that extra zero in a minute). That value is more specific than any selector, as long as it might be, without an ID, for example.
Comparison algorithm:
Go from left to right on the ranks.
Compare the ranks on both selectors.
The rank with the higher amount of point, wins.
If the ranks are equal, continue right to the next (less specific) rank.
If all ranks are equal, the one which comes later in the CSS document, wins.
More important notes:
The universal selector (*) has no specificity value (0,0,0,0) Pseudo-elements (e.g. :first-line) get 0,0,0,1 unlike their
pseudo-class brethren which get 0,0,1,0
The pseudo-class :not() adds no specificity by itself, only what's inside it's parentheses.
The !important directive can be applied on a single declaration, and adds a point to a "0th" rank, which is more specific than anything
else. So in the example above, adding !important on any rule will
bump the specificity value for that rule only to [1,0,1,1,2],
granting it an instant win over any other rules without !important.
Extra Reference
See this great article on the subject
How to determine which styles go to what element
The way the browser does it, is to go over the selector from right to left, and filtering elements out of the DOM as they go.
Going back to the previous example:
ul#nav li.active a
The browser does the following:
Take an a element.
Now check if it has an ancestor that is a li element with an .active class (this is through the descendant combinator: ancestor descendant).
Now check if it has a higher ancestor that is a ul with an ID of #nav (again, the descendant combinator is used).
If all these conditions are met for a certain element, then the styles are applied to it.
You can read it:
Select any a element
with an ancestor with a class of .active, which is also a li,
which in turn has an ancestor with an ID of #nav, which is also a ul.
You'll need to have a fully function and complete DOM tree to be able to successfully determine which element has what CSS styles.

CSS class repetition to increase specificity

According to the CSS docs:
http://www.w3.org/TR/CSS21/cascade.html#specificity
Specificity is defined by (amongst other things) the number of attributes and pseudo-classes in the selector.
So, my question is, is it possible to increase specificity by repeating the same classname over and over again?
For instance:
would
.qtxt.qtxt.qtxt.qtxt.qtxt
{
}
have a higher specificity than
.qtxt.lalgn
{
}
or
.lalgn .qtxt//(space added to create child selector)
{
}
?
Yes, it is possible and intentionally so. While this is not mentioned in the CSS2 spec, it is explicitly mentioned in the Selectors 3 spec:
Note: Repeated occurrances [sic] of the same simple selector are allowed and do increase specificity.
Therefore browsers must increase the specificity when encountering repeated simple selectors, as long as the selector is valid and applicable. This not only applies to repeated classes, but also applies to repeated IDs, attributes and pseudo-classes.
Given your code, .qtxt.qtxt.qtxt.qtxt.qtxt will have the highest specificity. The other two selectors are equally specific; combinators have no bearing in specificity calculations at all:
/* 5 classes -> specificity = 0-5-0 */
.qtxt.qtxt.qtxt.qtxt.qtxt
/* 2 classes -> specificity = 0-2-0 */
.qtxt.lalgn
/* 2 classes -> specificity = 0-2-0 */
.lalgn .qtxt
Also, the space in your last selector is the descendant combinator; the child combinator is >.
.qtxt.qtxt.qtxt would have the highest specificity...
http://jsfiddle.net/nXBTp/1/
However, this is only the case if you repeat the class name more times that any other selector, for example:
http://jsfiddle.net/nXBTp/2/
You shouldn't need to hack specificity like this... if you need to force a value, use !important.

CSS specificity or inheritance?

I've looked at similar questions here but I haven't found one particular to my case.
If I read this article correctly: http://css-tricks.com/specifics-on-css-specificity/
then what is happening doesn't make sense to me. Can someone explain if this is due to locality, inheritance or specificity please? I've stripped out all the unrelated css.
CSS
a:link {font-size:0.875em;color:#005984}
.button {color:#fff}
HTML
<a class="button">Awesome call to action</a>
I end up with a button that has blue text, instead of white. Now, a is an element, so it should have lower specificity than the .button class, should it not?
Thanks for your time.
This is due to specificity: although a is an element type selector which is less specific than a class selector, it's accompanied by a :link pseudo-class which is equally specific to your .button class. A type + pseudo-class will therefore be more specific than a class.
There is no inheritance going on here as there are no parent element styles that I can see being applied to your element. Inheritance refers to adopting styles from parent elements. When you see the link displaying blue instead of white, that's the cascade at work, not inheritance.
Locality isn't a CSS term (at least not in its glossary), so I'm not sure what you mean by that.
If you need your call-to-action button to be white, simply give it the a selector as well, so your selectors are equally specific and the last declaration will take precedence:
a:link {font-size:0.875em;color:#005984}
a.button {color:#fff}
A selector's specificity is calculated as follows:
- count the number of ID selectors in the selector (= a)
- count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
- count the number of type selectors and pseudo-elements in the selector (= c)
- ignore the universal selector
Selectors inside the negation pseudo-class are counted like any other, but the negation itself does not count as a pseudo-class.
Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.
So:
a:link
- a=0
- b=1
- c=1
- Result = 011
.button
- a=0
- b=1
- c=0
- Result = 010
Result: a:link is higher than .button.
Fix: :link won't work on anything but a tags anyway, so specifying a:link is redundant. Use :link instead, and that will fix the problem (provided .button is defined after :link)

Resources