Crafting exceptions to CSS rules has always been fairly straightforward with the use of classes, inheritance, and other selectors. For instance, given a general rule for links:
- a { text-decoration: none; background: black; color: white; }
…if we wanted particular links, which could appear multiple times on our web pages (but did not represent the majority of link content), to appear differently, we could create a class:
- a.highlighted { background: yellow; color: black; }
Things get more complicated if we add a :hover state to our links:
- a:hover { background: none; color: black; font-weight: bolder; }
As it uses a general selector, this rule would apply to all links when the mouse hovers over them, including our special highlighted class. Under traditional CSS, if we wanted to have a different hover effect for our highlighted links, we would have to write another declaration:
- a.highlighted:hover { background: yellow; font-style: italic; }
For a simple example like this, creation of exceptions is easy; obviously, the more special cases we have, the more negation of general CSS rules we would have to write to cover certain circumstances.
CSS3 provides another option: the :not pseudo-selector. :not allows you to say "the following CSS applies to all affected elements expect the following." Using our simple example above, if we wanted to affect the hover state of all links except those with a .highlighted class, we could write the following:
- a:hover:not(.highlighted) { background: none; color: black; font-weight: bolder; }
A better example might be the following: you have a form that contains a series of inputs. You want all inputs that are not text inputs to have a red background. The CSS to achieve this would be the following:
- input:not([type="text"]) { background: red; }
As a CSS3 selector, :not is supported in all modern browsers, including IE9 and higher.