web-dev-qa-db-fra.com

Pseudo-classe de négation CSS: not () pour les éléments parent / ancêtre

Ça me rend dingue:

HTML:

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

CSS:

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

Cela ne dit-il pas: "Sélectionner tout h1 éléments qui ont un ancêtre qui n'est pas un élément div ...? "Ainsi," Hello World! "ne doit pas être coloré en rouge, mais il l'est toujours.

Pour le balisage ci-dessus, l'ajout du combinateur enfant fonctionne:

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

Mais n'affecte pas le h1 élément s'il n'est pas enfant d'un élément div. Par exemple:

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

C'est pourquoi je voudrais indiquer le h1 élément en tant que descendant, et non enfant, de l'élément div. N'importe qui?

62
charles

Cela ne signifie-t-il pas: "Sélectionnez tous les éléments h1 Qui ont un ancêtre qui n'est pas un élément div ...?"

Cela fait. Mais dans un document HTML typique, chaque h1 A au moins deux ancêtres qui ne sont pas des éléments div - et ceux les ancêtres ne sont autres que body et html.

C'est le problème avec le filtrage des ancêtres à l'aide de :not(): cela ne fonctionne tout simplement pas de manière fiable, en particulier lorsque :not() n'est pas qualifié par un autre sélecteur tel qu'un sélecteur de type ou une classe sélecteur, par exemple .foo:not(div). Vous aurez beaucoup plus de facilité à appliquer simplement des styles à tous les éléments h1 Et à les remplacer par div h1.

Dans Selectors 4 , :not() a été amélioré pour accepter des sélecteurs complexes complets contenant des combinateurs, y compris le combinateur descendant. Si cela sera implémenté dans le profil rapide (et donc CSS) reste à tester et à confirmer, mais une fois implémenté, vous pourrez pouvoir pour l'utiliser pour exclure des éléments avec certains ancêtres. En raison du fonctionnement des sélecteurs, la négation doit être effectuée sur l'élément lui-même et non sur l'ancêtre afin de fonctionner de manière fiable, et donc la syntaxe sera un peu différente:

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

Quiconque connaît jQuery indiquera rapidement que ce sélecteur fonctionne dans jQuery aujourd'hui . C'est l'une des n certain nombre de disparités entre :not() du sélecteur 3 et :not() de jQuery , que les sélecteurs 4 cherchent à rectifier.

71
BoltClock

L'élément <html> N'est pas un <div>. L'élément <body> N'est pas un <div>.

La condition "a un ancêtre qui n'est pas un <div>" Sera donc vraie pour tous les éléments.

À moins que vous ne puissiez utiliser le sélecteur > (Enfant), je ne pense pas que vous puissiez faire ce que vous essayez de faire - cela n'a pas vraiment de sens. Dans votre deuxième exemple, <article> N'est pas un div, ce qui correspond également à *:not(div).

14
RichieHindle