How do CSS specificity levels between classes/pseudo-classes and elements/pseudo-elements work?
I'm using the following definitions (adapted from the CSS2 spec http://www.w3.org/TR/CSS21/cascade.html#specificity )
- a = using the style attribute on an element
- b = numb开发者_运维问答er of id attributes
- c = number of attributes (classes) and pseudo classes (:link, :hover)
- d = number of elements and pseudo-elements (:first-line, :first-letter)
With the following styles (my calculations to the right):
.content {color: green;} /* a=0 b=0 c=1 d=0 -> 0,0,1,0 */
.content:hover {color: yellow;} /* a=0 b=0 c=2 d=0 -> 0,0,2,0 */
li {color: orange;} /* a=0 b=0 c=0 d=1 -> 0,0,0,1 */
li:first-line {color: pink;} /* a=0 b=0 c=0 d=2 -> 0,0,0,2 */
and the following html
<li class="content">The first line</li>
When I open it up in a browser, the line of text is pink. I thought it would be green and on hover, it would be yellow. I thought that elements and pseudo-elements (the d in the calculation) have less weight than classes and pseudo classes (the c in the calculations).
Your understanding of specificity is completely correct. Pseudo-classes and classes are equal to each other in specificity, and both of them rank higher than pseudo-elements and elements (which are also equal to each other). This is explained pretty clearly at the spec you already linked to.
So why do the rules you set in li:first-line
take precedence over the ones you set in .content:hover
, if the latter is more specific?
Because, from CSS's perspective, pseudo-elements are elements. That means that you have a li:first-line
element which - if you didn't style it - would inherit color: green
or color: yellow
from the .content
and .content:hover
rules. But rules that target an element directly always take precedence over inherited rules, and your :first-line
selector is targeting a pseudo-element within your li
. The :first-line
rules win simply because they are not inherited and the rules from .content
and .content:hover
selectors are inherited (by the pseudo-element contained within the li
). Specificity rules are a red herring; they don't even come into play.
I guess that :first-line
is more specific than just .content
. So the first line of the text is pink, but the bullet of the list is green (and yellow on hover). Everything is good, as for me.
Imagine that the :first-line
selector is just a nested text node selector, like:
<li class="content">
<text:text>The first line</text:text><br />
The second line
</li>
It operates on the nested element, so it is more important than any other selector.
精彩评论