// css · Web Platform Advent #17
Il selettore CSS :has(): il selettore del genitore, spiegato (2026)
La pseudo-classe relazionale :has() permette di applicare stili a un elemento in base a cosa contiene o a cosa lo segue: il tanto atteso selettore del genitore. Come funziona, esempi reali, supporto dei browser e le insidie.
La pseudo-classe :has() e la funzionalita che gli autori CSS hanno chiesto per due decenni: un modo per applicare stili a un elemento in base a cosa si trova al suo interno, o a cosa viene dopo di esso. Di solito viene chiamata "selettore del genitore", anche se in realta e piu potente di cosi: e un selettore relazionale. Ora e disponibile in ogni browser moderno, quindi puoi usarla in produzione gia oggi.
L'idea di base
Un normale selettore CSS individua un elemento in base al suo tipo, alla sua classe o al suo stato. :has() ribalta il concetto: individua un elemento a causa degli elementi che contiene. Scrivi il genitore, poi :has(...) con un selettore per cio che deve trovarsi all'interno.
/* Style any .card that contains an <img> */
.card:has(img) {
padding: 0;
}
/* Style a <figure> only when it has a caption */
figure:has(figcaption) {
border: 1px solid #ddd;
} L'elemento che riceve effettivamente lo stile e quello prima di :has(): la .card e la figure, non l'immagine o la didascalia al loro interno. Questo e l'intero trucco: la condizione riguarda i discendenti, ma il bersaglio e l'antenato.
E relazionale, non solo "genitore"
Poiche puoi inserire combinatori dentro :has(), fa molto di piu che guardare i figli. Puoi reagire agli elementi fratelli, cosa che prima in CSS era impossibile.
/* A heading that is immediately followed by a paragraph */
h2:has(+ p) {
margin-bottom: 0.25rem;
}
/* A form that contains an invalid field */
form:has(input:invalid) {
border-left: 3px solid crimson;
}
/* A label whose related required input is empty and focused */
.field:has(input:required:placeholder-shown) .hint {
opacity: 1;
} Quel secondo esempio e proprio il tipo di cosa per cui in passato si ricorreva a JavaScript: cambiare l'aspetto di un intero form (o di qualsiasi contenitore) in base allo stato di un controllo al suo interno. Con :has() e una sola riga di CSS, e si aggiorna in tempo reale mentre l'utente digita.

Pattern pratici
- Query su quantita e contenuto: applica uno stile diverso a una galleria quando ha esattamente un'immagine rispetto a quando ne ha molte -
.gallery:has(img:only-child). - Stile sul fratello precedente: CSS poteva solo guardare in avanti con
+e~;:has()permette a un elemento precedente di reagire a uno successivo, per esempiolabel:has(+ input:checked). - Layout che si adatta al contenuto: dai a una card un layout a due colonne solo quando contiene effettivamente un'immagine, e a colonna singola quando non la contiene.
- Stati di form e validazione: evidenzia un intero fieldset quando un qualsiasi controllo al suo interno non e valido, senza una riga di script.
Supporto dei browser
Nel 2026 il supporto e ampio. :has() e arrivato in Chrome ed Edge 105 (agosto 2022) e in Safari 15.4, con Firefox che si e aggiunto nella versione 121 (dicembre 2023). Cio significa che ora e disponibile nelle versioni attuali di ogni browser principale, ed e sicuro affidarsi ad esso per la maggior parte del pubblico. Per i browser piu vecchi puoi trattare gli stili con :has() come un miglioramento progressivo, dato che un browser che non comprende il selettore semplicemente ignora la regola.
Insidie da conoscere
- Non puoi individuare pseudo-elementi dentro :has(). Selettori come
::beforenon sono ammessi come argomento. - :has() stesso non e ammesso dentro :has(). Non puoi annidare un controllo relazionale dentro un altro.
- Mantieni ragionevole l'ambito. Selettori molto ampi come
body:has(...)che costringono il browser a ricontrollare grandi porzioni della pagina possono costare in prestazioni su documenti grandi e aggiornati di frequente. In pratica, i selettori limitati ai componenti vanno bene; i motori hanno ottimizzato i casi comuni. - Il bersaglio e il soggetto, non la corrispondenza. Se una regola non viene applicata, controlla di stare applicando lo stile all'elemento prima di
:has(), non a quello al suo interno.
FAQ
:has() e davvero il selettore del genitore in CSS? In sostanza si, e anche di piu. Seleziona un antenato in base ai suoi discendenti, che e il classico caso d'uso del "selettore del genitore", ma poiche accetta combinatori puo anche selezionare in base ai fratelli successivi, quindi e meglio descritto come selettore relazionale.
Posso usare :has() in produzione nel 2026? Per la maggior parte dei siti, si: e supportato nelle versioni attuali di tutti i browser principali. Usalo come miglioramento progressivo se devi supportare browser molto vecchi.
:has() danneggia le prestazioni? Raramente, se mantieni i selettori limitati. Controlli :has() estremamente ampi, a livello di intero documento, su pagine grandi e in continua modifica possono aggiungere costi, ma l'uso a livello di componente va bene.
Per altro CSS moderno, vedi le nostre guide sul nesting nativo in CSS e sulle container query.