soy Kseso y esto EsCSS

Pseudoclase Css :has() Selector de padre o elemento precedente

El nunca nacido selector Css de padre, anterior o precedente se reinventa y redefine y ahora es la pseudoclase :has()

Pseudoclase Css :has() Selector de padre o elemento precedente

·Por Kseso ✎ 2
Pseudoclase Css :has() Selector de padre o elemento precedente. O de cómo remontar el DOM con puro Css

El último documento del W3c que desarrolla los selectores Css Selectors Level 4 (status editors’ draft) apareció publicado el día 28 de Mayo. Una ausencia es notoria: no hay ni rastro del famoso selector de padre, ancestro o precedente tal como hasta ahora era referenciado en muchas partes.

Pero junto a esa ausencia hay una nueva pseudoclase que creo va a suplir al nunca nacido "selector de padre". Es la que los editores han llamado The Relational Pseudo-class: :has().

La pseudoclase :has() de Css

Los editores en la presentación de esta pseudoclase la explican en tres líneas:

The relational pseudo-class, :has(), is a functional pseudo-class taking a relative selector list as an argument. It represents an element if any of the relative selectors, when absolutized and evaluated with the element as the :scope elements, would match at least one element.

Mucho más efectiva que todo lo que se había hablado hasta ahora sobre el selector de padre y su sintaxis.

La pseudoclase :has() admite dentro del paréntesis una lista de elementos como argumento para estilizarlo en función de ese argumento . Esto es, puedes aplicar estilos a un elemento en función de lo que le siga en el DOM.

Y en el argumento puedes incluir los combinadores de selectores (>, + ~ ...) para seleccionar no sólo al padre o abuelo sino también a hermanos precedentes. También puede incluir clases o id´s.

Los ejemplos del documento ayudan a comprenderla mejor que las palabras:

a:has(> img) { }

El selector anterior se aplicará sólo a los enlaces que contengan una imagen como hijo directo del enlace.

h2:has(+ h3) { }

Estiliza todos los 'h2' que tengan un h3 inmediatamente después de ellos. O leído al revés, apunta al hermano precedente de los 'h3' si y sólo si es un 'h2'.

La pesudoclase de Css :has() no se queda sólo en apuntar hacia arriba del DOM si hay algo. Puede usarse con otras pseudoclases como la de negación :not() para lo contrario: apuntar a un precedente si no se cumple lo indicado en el argumento.

ul:has(:not(li + li)) { }

Seleccionas todas las listas de un sólo ítem de lista. El documento Selectores level 4 resalta que el orden de las dos pseudoclases es intercambiable. Se podrá colocar cualquiera de ellas dentro o fuera del argumento de la otra. El selector anterior es equivalente a ul:not(:has(li + li)).

El argumento puede estar constituidos por múltiples valores separados por comas (,), en cuyo caso basta con que uno de los múltiples valores se cumpla para que aplique la regla.

section:not(:has(h1, h2, h3, h4, h5, h6)) { }

El selector anterior selecciona los <section> que no contienen ningún elemento de los indicados en el argumento (dentro del paréntesis). Basta con que tenga uno cualquiera de los indicados para que no se aplique la regla (nota la pseudoclase :not)

¿Y el caso contrario, seleccionar un elemento si y sólo si contiene dos elementos (o más)? Lo que viene siendo el operador lógico and. Me asaltó la duda y pregunté al editor del documento, @tabatkins, si el argumento de la pseudoclase :has() podría contener estos operadores lógicos.

Como ves en el tuit de respuesta hay dos dudas despejadas por el precio de una: el cómo hacerlo y que es posible encadenar la pseudoclase :has() varias veces al mismo elemento:

.elemento:has(header):has(article) { }

Las posibilidades y el campo abierto por esta nueva pseudoclase creo que es enorme. Css por fin define una herramienta para hacer lo que hasta ahora era imposible: remontarse en el DOM para estilizar cualquier elemento precedente a otro en función de la existencia o no de otros contenidos.

Tiempos interesantes. Habrá que estar atentos a su evolución en documentos posteriores y a su implementación por parte de los navegadores.

Déjame terminar este artículo preguntándote tu opinión sobre esta novedad e invitándote a que dejes volar tu imaginación y nos cuentes un caso imaginativo y creativo de uso del selector de pseudoclase :has()

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso