Unfortunately, in Selectors 3, that's the best you can do since :not()
only accepts a single simple selector. Having said that, the selector in your overriding rule can be replaced with input.red.red
— you don't need more class selectors than attribute selectors unless that rule has to appear earlier in the stylesheet.
This is another problem that Selectors 4 solves with its enhancement of :not()
: specificity. In Selectors 4, you will be able to replace all those negations with just one :not()
pseudo, effectively decreasing its specificity within your original selector to just one attribute selector. From section 16:
The specificity of a :not() pseudo-class is replaced by the specificity of the most specific complex selector in its selector list argument.
Since any attribute selector is equally specific to a class selector, the specificity of any number of lone attribute selectors in a list will never be more than that of just one of them. This allows you to get away with using just one class selector for your override without having to repeat it.
The following works in Safari as a proof-of-concept:
/* 1 type, 2 attributes -> specificity = (0, 2, 1)
input:not([type="checkbox"]):not([type="radio"]),
1 type, 1 attribute -> specificity = (0, 1, 1) */
input:not([type="checkbox"], [type="radio"]) {
background-color: blue;
}
/* 1 type, 1 class -> specificity = (0, 1, 1) */
input.red {
background-color: red;
}
<input type="checkbox">
<input type="radio">
<input type="text">
<input class="red" type="text">
!important
to override specificity. – Barnyard.red.red.red
is a better solution than!important
. – Statics