Pseudoclase de negación CSS: not() para elementos padre/ancestro
Esto me está volviendo loco:
HTML:
<div><h1>Hello World!</h1></div>
CSS:
*:not(div) h1 { color: #900; }
¿No dice esto: "Seleccione todos h1
los elementos que tengan un antepasado que no sea un div
elemento...?" 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 h1
elemento si no es hijo de un div
elemento. Por ejemplo:
<div><article><h1>Hello World!</h1></article></div>
Es por eso que me gustaría indicar el h1
elemento como descendiente, no hijo, del div
elemento. ¿Alguien?
¿No dice esto: "Seleccione todos
h1
los elementos que tengan un antepasado que no sea undiv
elemento...?"
Lo hace. Pero en un documento HTML típico, cada h1
tiene al menos dos ancestros que no son div
elementos, y esos ancestros no son otros que body
y 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 h1
los 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.
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.