I have this small HTML:
<div id="column">
<div class="ticker">
<ul>
<li>Item 1</li>
</ul>
</div>
</div>
For ul
elements outside of the .ticker
class, but inside of the #column
id exists this CSS:
#column ul:not(.a):not(.b) {
margin: 1em;
}
But inside the .ticker
class I don't want this margin. So I thought I could use:
#column .ticker ul {
margin: 0;
}
That said, I know that the specificity of the first CSS selector is higher because of the two :not()
pseudo classes. But to get a higher specificity I had to append those two :not()
in the second CSS snippet to the ul
, too. So that works:
#column .ticker ul:not(.c):not(.d) {
margin: 0;
}
Isn't that stupid? In fact it doesn't matter what you use in the two :not()
pseudo classes. They just have to be there. This doesn't make any sense to me.
Is that simply a part of CSS3 which is not perfect or is there a solution which my brain didn't come up with yet?
See it in action here: http://jsfiddle.net/9BDw5/2/
The :not() pseudo class does not add to the selector specificity, unlike other pseudo-classes.
Rule 3: Inline CSS has the highest specificity. Inline CSS is the closest to the HTML element, so it is more specific and is therefore applied.
In CSS, to exclude a particular class, we can use the pseudo-class :not selector also known as negation pseudo-class or not selector. This selector is used to set the style to every element that is not the specified by given selector. Since it is used to prevent a specific items from list of selected items.
Specificity Hierarchy :Every element selector has a position in the Hierarchy. Inline style: Inline style has highest priority. Identifiers(ID): ID have the second highest priority. Classes, pseudo-classes and attributes: Classes, pseudo-classes and attributes are come next.
It's not just you; this is indeed one of the fundamental pitfalls of specificity as a CSS concept.
A simpler solution that is equally valid would be to repeat your .ticker
class selector so you have this:
#column .ticker.ticker ul {
margin: 0;
}
This way you do not have to modify your element to add an extra class just for the sake of increasing selector specificity.
The spec verifies this:
Note: Repeated occurrances of the same simple selector are allowed and do increase specificity.
On a side note, remember that the specificity of the :not()
pseudo-class is strictly defined (in the same section of the spec) as equal to that of its argument. So :not(#id)
and #id
have the same specificity, and likewise for :not(E):not(.a)
and E.a
. The :not
portion does not count at all, not even as a pseudo-class.
This limitation in specificity will be addressed in Selectors 4, which enhances :not()
to accept a comma-delimited list of selectors. The specificity of a :not()
that contains a selector list will be that of the most specific selectors in the list, so the specificity of ul:not(.c, .d)
is equal to 1 type selector and 1 class selector, compared to ul:not(.c):not(.d)
which is equal to 1 type selector and 2 class selectors. This makes it tremendously useful in excluding any number of classes from a match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With