Pseudoclase de negación CSS: not() para elementos padre/ancestro

Resuelto charles asked hace 13 años • 2 respuestas

Esto me está volviendo loco:

HTML:

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

CSS:

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

¿No dice esto: "Seleccione todos h1los elementos que tengan un antepasado que no sea un divelemento...?" Por tanto, "¡Hola mundo!" No debería ser de color rojo, pero todavía lo es.

Para el marcado anterior, agregar el combinador secundario funciona:

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

Pero no afecta al h1elemento si no es hijo de un divelemento. Por ejemplo:

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

Es por eso que me gustaría indicar el h1elemento como descendiente, no hijo, del divelemento. ¿Alguien?

charles avatar Aug 17 '11 02:08 charles
Aceptado

¿No dice esto: "Seleccione todos h1los elementos que tengan un antepasado que no sea un divelemento...?"

Lo hace. Pero en un documento HTML típico, cada h1 tiene al menos dos ancestros que no son divelementos, y esos ancestros no son otros que bodyy html.

Este es el problema al intentar filtrar ancestros usando :not(): simplemente no funciona de manera confiable, especialmente cuando :not()no está siendo calificado por algún otro selector, como un selector de tipo o un selector de clase, por ejemplo .foo:not(div). Le resultará mucho más fácil simplemente aplicar estilos a todos h1los elementos y anularlos con div h1.

En Selectores 4 , :not()se ha mejorado para aceptar selectores complejos completos que contienen combinadores, incluido el combinador descendiente. Queda por probar y confirmar si esto se implementará en el perfil rápido (y por lo tanto en CSS), pero una vez que se implemente, podrá usarlo para excluir elementos con ciertos ancestros. Debido a cómo funcionan los selectores, la negación debe realizarse en el elemento en sí y no en el ancestro para que funcione de manera confiable y, por lo tanto, la sintaxis se verá un poco diferente:

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

Cualquiera que esté familiarizado con jQuery rápidamente señalará que este selector funciona en jQuery actualmente . Esta es una de varias disparidades entre Selector 3 :not()y jQuery:not() , que Selectors 4 busca rectificar.

BoltClock avatar Aug 16 '2011 19:08 BoltClock

El <html>elemento no es un <div>. El <body>elemento no es un <div>.

Entonces, la condición "tiene un antepasado que no es <div>" será cierta para todos los elementos.

A menos que puedas usar el >selector (secundario), no creo que puedas hacer lo que intentas hacer; realmente no tiene sentido. En su segundo ejemplo, <article>no es un div, por lo que *:not(div)también coincide.

RichieHindle avatar Aug 16 '2011 19:08 RichieHindle