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

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.

Related

Can pseudo-elements be used alone in CSS?

According to W3C, the definition of a selector does not cover a pseudo-element:
https://www.w3.org/TR/css3-selectors/#selector-syntax
The above link says:
A selector is a chain of one or more sequences of simple selectors
separated by combinators.
and it also says:
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.
Regarding how a pseudo-element should be used, it says:
One pseudo-element may be appended to the last sequence of simple
selectors in a selector.
and
Only one pseudo-element may appear per selector, and if present it
must appear after the sequence of simple selectors that represents the
subjects of the selector.
So does that mean that a pseudo-element can only be a suffix to a "valid" selector and should not be used alone?
does that mean that a pseudo-element can only be a suffix to a "valid"
selector and should not be used alone?
Your conclusion is not true, because the universal selector * can be omitted.
If a universal selector represented by * [...] is immediately
followed by a pseudo-element, then the * may be omitted and the
universal selector's presence implied.
So you can use a pseudo-element alone, e.g. ::before, because under the hood it will be treated like *::before.
::before {
content: 'Hello!';
}

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

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.

CSS Object Resolution

If two classes in CSS have the same derived class how does CSS resolve the proper class?
For example:
.ClassA.Left {}
.ClassB.Left {}
.Left {}
Since the class 'Left' can be applied to any object how can I be assured it is the one I want?
What priority is used to bind 'Left'?
Anything with .Left as a class will get the styles applied in .Left, unless it also has ClassA (class="Left ClassA") then it will get the styles from .Left and .ClassA.Left, with ClassA.Left taking priority since it has higher specificity. Same rules apply to class="Left ClassB".
See here about specificity: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
Specificity
The concept
Specificity is the means by which a browser decides which property
values are the most relevant to an element and gets to be applied.
Specificity is only based on the matching rules which are composed of
selectors of different sorts.
How is it calculated?
The specificity is calculated on the concatenation of the count of
each selectors type. It is not a weight that is applied to the
corresponding matching expression.
In case of specificity equality, the latest declaration found in the
CSS is applied to the element.
Note: Proximity of elements in the document tree has no effect on the
specificity.
Crescent order of specificity
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style
The !important exception
When an !important rule is used on a style declaration, this
declaration overrides any other declaration made in the CSS, wherever
it is in the declaration list. Although, !important has nothing to do
with specificity.
The :not exception
The negation pseudo-class :not is not considered as a pseudo-class in
the specificity calculation. Although, selectors placed into the
negation pseudo-class count as normal selectors.
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
Equally, if the element had all three classes (ClassA, ClassB and Left) the the order in which the classes are listed in your CSS sheet matters.
.ClassA.Left would be beaten by .ClassB.Left (for common properties) as .ClassB.Left was lower in the cascade.
Single class selectors are beaten by multiple class selectors, thus .ClassA.Left beats .ClassA
Source order of the classes in the HTML is not a factor.
Codepen Specificity Example

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