CSS-Negationspseudoklasse: not () für Eltern- / Vorfahrenelemente

76

Das macht mich verrückt:

HTML:

<div><h1>Hello World!</h1></div>

CSS:

*:not(div) h1 { color: #900; }

Lautet dies nicht: "Wählen Sie alle h1Elemente aus, deren Vorfahr kein divElement ist ...?" Also "Hallo Welt!" sollte nicht rot gefärbt sein, ist es aber immer noch.

Für das obige Markup funktioniert das Hinzufügen des untergeordneten Kombinators wie folgt:

*:not(div) > h1 { color: #900; }

Betrifft das h1Element jedoch nicht , wenn es kein untergeordnetes Element eines divElements ist. Zum Beispiel:

<div><article><h1>Hello World!</h1></article></div>

Aus diesem Grund möchte ich das h1Element als Nachkommen und nicht als Kind des divElements angeben . Jemand?

Charles
quelle
6
Nebenbei bemerkt, sobald Sie eine andere Art von Selektor verwenden, können Sie den *, dh :not(div)genau so, wie Sie ihn angegeben haben, .classoder #idohne den sofort löschen *.
BoltClock

Antworten:

85

Lautet dies nicht: "Wählen Sie alle h1Elemente aus, deren Vorfahr kein divElement ist ...?"

Es tut. In einem typischen HTML-Dokument hat jeder h1 mindestens zwei Vorfahren, die keine divElemente sind - und diese Vorfahren sind keine anderen als bodyund html.

Dies ist das Problem beim Versuch, Vorfahren zu filtern :not(): Es funktioniert einfach nicht zuverlässig, insbesondere wenn das :not()nicht von einem anderen Selektor wie einem Typ-Selektor oder einem Klassen-Selektor qualifiziert wird, z .foo:not(div). Es fällt Ihnen viel leichter, Stile auf alle h1Elemente anzuwenden und sie zu überschreiben div h1.

In Selektoren 4 , :not()wurde erweitert volle komplexe Selektoren enthält Kombinatoren zu akzeptieren, einschließlich der Nachkomme Kombinator. Ob dies in dem schnellen Profil (und damit CSS) implementiert wird , bleibt geprüft und bestätigt werden, aber sobald sie umgesetzt wird, dann Sie werden die Lage sein , es zu verwenden , um Elemente mit bestimmten Vorfahren auszuschließen. Aufgrund der Funktionsweise von Selektoren muss die Negation für das Element selbst und nicht für den Vorfahren durchgeführt werden, um zuverlässig zu arbeiten. Daher sieht die Syntax etwas anders aus:

h1:not(div h1) { color: #900; }

Jeder, der mit jQuery vertraut ist, wird schnell darauf hinweisen, dass dieser Selektor heute in jQuery funktioniert . Dies ist einer von mehreren Unterschieden zwischen Selector 3 :not()und jQuery:not() , die Selectors 4 zu korrigieren versucht.

BoltClock
quelle
Gibt es eine Lösung, um so etwas mit Selectors Level 3 zu machen?
Alexandre D.
1
@Alexandre D.: Wenn es das gegeben hätte, hätte ich es erwähnt. Das Beste, was Sie tun können, ist, wie ich bereits sagte, "Stile auf alle h1-Elemente anzuwenden und sie mit div h1 zu überschreiben".
BoltClock
16

Das <html>Element ist kein <div>. Das <body>Element ist kein <div>.

Die Bedingung "hat einen Vorfahren, der kein a ist <div>" gilt also für alle Elemente.

Wenn Sie den >(untergeordneten) Selektor nicht verwenden können, können Sie nicht das tun, was Sie versuchen - es macht keinen Sinn. In Ihrem zweiten Beispiel <article>ist kein div, also passt das *:not(div)auch.

RichieHindle
quelle
3
"alle Elemente" außer htmlnatürlich, da es ein Wurzelelement ist, nicht dass es hier wichtig ist :)
BoltClock