Seguici su:
Programmazione Web Italia

Il selettore :has() in CSS - descrizione ed esempi pratici

Il selettore :has(), proposto nelle specifiche CSS level 4, fin dalla fine del 2023 è adottato dalla maggior parte dei browser: è giunto il momento di capire come utilizzare questa nuova opportunità.

Il selettore :has() in CSS4

Il selettore :has() è una delle 4 pseudo-classi funzionali (insieme a: :is(); :where() e :not()) e consente agli sviluppatori di selezionare elementi del DOM che contengono al loro interno elementi che rispondono al selettore passato come parametro nella funzione :has(). E' essenzialmente un selettore che permentte di ottenere il "parent" degli elementi definiti attraverso il parametro.

Provo a fare un semplice esempio chiarificatore...

Esempio 1 - selettore CSS :has()

a:has(img)

L'istruzione CSS qui sopra seleziona tutti gli elementi <a> che hanno al loro interno un elemento <img>.

Altri esempi

Il selettore :has() può essere usato per in congiunzione con combinator o pseudo-selettori e può essere anche concatenato.

Esempio 2 - selettore CSS :has() in query più complesse

/* Seleziona un <dt> che è immediatamente seguito da un ulteriore <dt> */
dt:has(+ dt)
/* In combinazione con :not() per selezionare elementi <section> che non hanno titoli al loro interno */ 
section:not(:has(h1, h2, h3, h4, h5, h6))
 
/* L'ordine dei selettori usati ha rilevanza: qui si selezionano le <section> 
che hanno qualsiasi elemento che non sia un titolo */ 
section:has(:not(h1, h2, h3, h4, h5, h6))
/* E' possibile concatenare i selettori :has() */
article:has(h2):has(ul)
/* In combinazione con il selettore :is() */
:is(h1, h2, h3):has(+ :is(h2, h3, h4))

L'utilizzo di questo selettore permette di creare combinazioni veramente efficaci ma il rischio è quello di creare query poco comprensibili e potenzialmente poco performanti, sta allo sviluppatore utilizzarlo con il giusto criterio.

Attenzione: non è possibile annidare :has() e utilizzare pseudo-elementi

Se da un lato la concatenzaione di più selettori :has() è permessa (vedi esempio sopra), il "nesting" di tale selettore non è permesso a causa dei problemi di performance e di complessità logica che ne deriverebbero.

Per ragioni simili anche l'utilizzo di pseudo-elementi dentro il selettore :has() è sconsigliato; in più la loro validità condizionale potrebbe introdurre cicli logici difficilmente gestibili.

Compatibilità