This is driving me nuts:
HTML:
<div><h1>Hello World!</h1></div>
CSS:
*:not(div) h1 { color: #900; }
Doesn't this read, "Select all h1
elements that have an ancestor that is not a div
element...?" Thus, "Hello World!" should not be coloured red, yet it still is.
For the above markup, adding the child combinator works:
*:not(div) > h1 { color: #900; }
But doesn't affect the h1
element if it is not a child of a div
element. For example:
<div><article><h1>Hello World!</h1></article></div>
Which is why I'd like to indicate the h1
element as a descendant, not a child, of the div
element. Anyone?
The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class.
There is currently no way to select the parent of an element in CSS in a way that works across all browsers. That said, the Selectors Level 4 Working Draft includes a :has() pseudo-class that will provide this capability.
Definition and UsageThe element>element selector is used to select elements with a specific parent. Note: Elements that are not directly a child of the specified parent, are not selected.
The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list. This is useful for writing large selectors in a more compact form.
Doesn't this read, "Select all
h1
elements that have an ancestor that is not adiv
element...?"
It does. But in a typical HTML document, every h1
has at least two ancestors that are not div
elements — and those ancestors are none other than body
and html
.
This is the problem with trying to filter ancestors using :not()
: it just doesn't work reliably, especially when the :not()
is not being qualified by some other selector such as a type selector or a class selector, e.g. .foo:not(div)
. You'll have a much easier time simply applying styles to all h1
elements and overriding them with div h1
.
In Selectors 4, :not()
has been enhanced to accept full complex selectors containing combinators, including the descendant combinator. Whether this will be implemented in the fast profile (and thus CSS) remains to be tested and confirmed, but once it is implemented, then you will be able to use it to exclude elements with certain ancestors. Due to how selectors work, the negation has to be done on the element itself and not the ancestor in order to work reliably, and therefore the syntax will look a little different:
h1:not(div h1) { color: #900; }
Anyone who's familiar with jQuery will quickly point out that this selector works in jQuery today. This is one of a number of disparities between Selector 3's :not()
and jQuery's :not()
, which Selectors 4 seeks to rectify.
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