back to top

I 5 selettori CSS meno conosciuti ma potentissimi

Introduzione

Nel vasto e dinamico mondo dello sviluppo frontend, padroneggiare il CSS è fondamentale per creare interfacce utente non solo belle da vedere, ma anche performanti, accessibili e, soprattutto, facili da mantenere. Molti developer conoscono e utilizzano quotidianamente i selettori CSS di base: tag, classi, ID. Tuttavia, il vero potenziale dei fogli di stile emerge quando ci si addentra nei meandri dei selettori più avanzati.

Conoscere e applicare i selettori CSS meno conosciuti può sembrare un dettaglio, ma credetemi, cambia radicalmente il modo in cui approcciate lo styling. Vi permette di scrivere codice più pulito, ridurre la dipendenza da JavaScript per logiche di presentazione, risolvere problemi di layout complessi con eleganza e migliorare l’efficienza del vostro markup. In questo articolo, esploreremo 5 selettori che forse non usate abitualmente, ma che, una volta compresi, diventeranno strumenti potentissimi nella vostra cassetta degli attrezzi frontend. Preparatevi a scoprire gemme nascoste che renderanno il vostro CSS più intelligente e potente.


I Selettori al Microscopio

Analizziamo da vicino questi strumenti. Per ciascun selettore, vedremo una breve spiegazione teorica, i suoi vantaggi principali e un esempio pratico per vederlo in azione.

1. :is() e :where(): Eleganza e Controllo della Specificità

Queste due pseudo-classi funzionali, pur essendo strettamente correlate, offrono potenti meccanismi di raggruppamento e controllo della specificità, rendendo il vostro CSS incredibilmente più leggibile e modulare.

Spiegazione:

  • :is(<lista-selettori>): Corrisponde a qualsiasi elemento che corrisponde a qualsiasi selettore nella lista fornita come argomento. Il suo superpotere (e talvolta insidia) è che la sua specificità è pari alla specificità del selettore più specifico all’interno della lista.
  • :where(<lista-selettori>): Funziona in modo identico a :is() per il raggruppamento, ma con una differenza cruciale: la sua specificità è sempre zero.

Vantaggi:

  • Riduzione della Ripetizione: Raggruppate selettori multipli che condividono le stesse regole di stile in un’unica dichiarazione, eliminando la necessità di ripetere blocchi di codice.
  • Leggibilità: Il vostro CSS diventa molto più pulito e facile da leggere, specialmente con selettori complessi.
  • Controllo della Specificità: :where() è ideale per scrivere librerie, framework o CSS di base dove non volete che i vostri stili “iniziali” abbiano una specificità elevata, permettendo agli sviluppatori di sovrascriverli facilmente. :is() è utile quando volete che il raggruppamento mantenga la specificità del selettore più forte.

Esempio Pratico:

Immaginate di voler applicare uno stile di base a tutti i titoli (h1, h2, h3, h4) o a un gruppo di elementi con classi diverse (.card, .widget, .modal).

<main>
    <h1>Titolo Principale</h1>
    <section>
        <h2>Sottotitolo Sezione</h2>
        <p>Questo è un paragrafo.</p>
    </section>
    <div class="card">
        <h3>Titolo Card</h3>
        <p>Contenuto della card.</p>
    </div>
</main>
/* CSS ripetitivo */
h1, h2, h3, h4 {
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    line-height: 1.2;
}

.card, .widget, .modal {
    border: 1px solid #ddd;
    padding: 1em;
    border-radius: 8px;
}

Con :is() o :where():

/* Con :is() */
:is(h1, h2, h3, h4) {
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    line-height: 1.2;
}

:is(.card, .widget, .modal) {
    border: 1px solid #ddd;
    padding: 1em;
    border-radius: 8px;
}

/* Esempio di specificità:
   Questo sovrascriverà il bordo selettore con :is(.card, .widget, .modal)
   perché .card ha specificità maggiore (10) rispetto a un ipotetico .modal#id (110)
   e :is() prende la specificità maggiore della lista.
*/
.card {
    border-color: blue;
}

Con :where():

/* Con :where() */
:where(h1, h2, h3, h4) {
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    line-height: 1.2;
}

:where(.card, .widget, .modal) {
    border: 1px solid #ddd;
    padding: 1em;
    border-radius: 8px;
}

/* Esempio di specificità:
   Questo sovrascriverà il bordo selettore con :where(.card, .widget, .modal)
   anche se .card ha specificità 10 e :where() ha specificità 0,
   perché .card è più specifico di 0.
*/
.card {
    border-color: green;
}

Come vedete, :where() è perfetto per resettare o definire stili di base che devono essere facilmente sovrascrivibili, mentre :is() mantiene la specificità, utile in molti contesti applicativi. Sono selettori CSS meno conosciuti ma estremamente utili per la pulizia e la gestione del codice.

2. :has(): Il “Parent Selector” Finalmente Tra Noi (o quasi)

Per anni, i developer CSS hanno sognato un modo per selezionare un elemento genitore basato sui suoi discendenti. Selettori come :has() realizzano finalmente questo sogno, aprendo scenari di styling altrimenti impossibili senza JavaScript.

Spiegazione:

La pseudo-classe :has(<selettori-relativi>) seleziona un elemento se almeno uno dei selettori relativi passati come argomento corrisponde a un discendente (o a un fratello) dell’elemento. In pratica, vi permette di condizionare lo stile di un elemento alla presenza o alle proprietà di un altro elemento al suo interno o nelle vicinanze.

Vantaggi:

  • Styling basato sul Contenuto: Modificate lo stile di un contenitore a seconda di cosa contiene (es. una card che contiene un’immagine, un div che contiene un input valido/invalido).
  • Interazioni Complesse: Implementate logiche di styling che prima richiedevano JavaScript (es. rendere un’etichetta di un form rossa se l’input associato è invalido, senza classi aggiuntive sull’etichetta o sul genitore).
  • CSS più Semantico: Potete basare gli stili sulla struttura HTML senza aggiungere classi unicamente per scopi di styling.

Esempio Pratico:

Vogliamo stilizzare diversamente una card che contiene un’immagine rispetto a una che contiene solo testo. Vogliamo anche evidenziare un campo form se contiene un input con un errore.

<div class="card-container">
    <div class="card-item">
        <img src="image.jpg" alt="Immagine di esempio">
        <p>Questa card ha un'immagine.</p>
    </div>

    <div class="card-item">
        <p>Questa card ha solo testo.</p>
    </div>
</div>

<form>
    <div class="form-group">
        <label for="email">Email:</label>
        <input type="email" id="email" required>
    </div>
    <div class="form-group">
        <label for="password">Password:</label>
        <input type="password" id="password" required value="short">
    </div>
</form>

CSS con :has():

/* Stile di base per tutte le card */
.card-item {
    border: 1px solid #ddd;
    padding: 1em;
    margin-bottom: 1em;
    border-radius: 8px;
    transition: border-color 0.3s ease;
}

/* Stile per le card che CONTENGONO un'immagine */
.card-item:has(img) {
    border-color: blue;
    background-color: #eef;
}

/* Stile per il gruppo form che CONTIENE un input invalido */
.form-group:has(input:invalid) {
    border: 2px solid red;
    padding: 0.5em; /* Aggiungiamo un po' di padding per visibilità */
    border-radius: 4px;
}

/* Stile per l'etichetta all'interno di un gruppo form che CONTIENE un input invalido */
.form-group:has(input:invalid) label {
    color: red;
    font-weight: bold;
}

input:invalid {
    border-color: red;
}

Questo esempio dimostra come :has() permetta di selezionare elementi genitori (.card-item, .form-group) in base allo stato o alla presenza di elementi figli (img, input:invalid). È incredibilmente potente per gestire stati complessi dell’interfaccia utente senza ricorrere a manipolazioni del DOM via JavaScript. La compatibilità browser per :has() è migliorata drasticamente di recente, rendendolo uno dei selettori CSS meno conosciuti ma più entusiasmanti da usare oggi.

3. Selettori di Attributo Avanzati ([attr*=""], [attr^=""], [attr$=""])

I selettori di attributo di base ([attr], [attr="value"]) sono abbastanza comuni. Tuttavia, le varianti che permettono di cercare sottostringhe, prefissi o suffissi offrono un livello di flessibilità spesso trascurato, permettendo di stilizzare elementi in base a parte del valore di un attributo.

Spiegazione:

  • [attribute*="value"]: Seleziona gli elementi il cui attributo attribute contiene la sottostringa “value” in qualsiasi posizione.
  • [attribute^="value"]: Seleziona gli elementi il cui attributo attribute inizia con la stringa “value”.
  • [attribute$="value"]: Seleziona gli elementi il cui attributo attribute finisce con la stringa “value”.

Vantaggi:

  • Targeting Flessibile: Stilizzate elementi basandovi su pattern nei loro attributi (es. tutti i link che puntano a un certo dominio, tutte le immagini con un certo prefisso nel nome file, tutti i link a PDF).
  • Meno Classi CSS: Riducete la necessità di aggiungere classi CSS specifiche (.link-esterno, .file-pdf) per scopi di styling basati sugli attributi.
  • Automazione: Utile in scenari dove i valori degli attributi sono generati dinamicamente (es. da un CMS o un backend) e non potete controllare facilmente l’aggiunta di classi specifiche.

Esempio Pratico:

Vogliamo aggiungere un’icona specifica ai link esterni, ai link a file PDF e stilizzare diversamente le immagini “thumbnail”.

<nav>
    <a href="/pagina-interna">Pagina interna</a>
    <a href="https://www.google.com" target="_blank">Google (esterno)</a>
    <a href="/documenti/report.pdf">Report PDF</a>
    <a href="mailto:email@example.com">Invia Email</a>
</nav>

<img src="/immagini/thumbnail-paesaggio.jpg" alt="Thumbnail Paesaggio">
<img src="/immagini/foto-ritratto.jpg" alt="Foto Ritratto">

CSS con selettori di attributo avanzati:

/* Stile per i link esterni (che iniziano con http:// o https://) */
a[href^="http://"],
a[href^="https://"] {
    color: blue;
    text-decoration: underline;
    /* Aggiungi un'icona esterna usando pseudo-elemento (richiede un'immagine o SVG di sfondo) */
    padding-right: 18px; /* Spazio per l'icona */
    background: url('external-link.svg') no-repeat right center;
    background-size: 14px 14px;
}

/* Stile per i link a file PDF (che finiscono con .pdf) */
a[href$=".pdf"] {
    color: red;
    font-weight: bold;
    /* Aggiungi un'icona PDF */
    padding-right: 18px; /* Spazio per l'icona */
    background: url('pdf-icon.svg') no-repeat right center;
    background-size: 14px 14px;
}

/* Stile per le immagini il cui 'alt' contiene "Thumbnail" */
img[alt*="Thumbnail"] {
    border: 2px solid green;
    border-radius: 4px;
}

Questi selettori offrono un modo dichiarativo e potente per agganciare stili basati su pattern negli attributi, rendendo il vostro CSS più dinamico e meno dipendente da classi strutturali. Sono selettori CSS meno conosciuti rispetto ai loro cugini base, ma estremamente versatili.

4. :focus-within: Stati Dinamici Senza JavaScript

La pseudo-classe :focus è indispensabile per l’accessibilità e l’usabilità, evidenziando l’elemento interattivo attualmente attivo. :focus-within estende questo concetto, permettendoti di stilizzare un elemento contenitore quando uno qualsiasi dei suoi discendenti (o l’elemento stesso) riceve il focus.

Spiegazione:

La pseudo-classe :focus-within seleziona un elemento (o uno qualsiasi dei suoi antenati) se l’elemento stesso o uno qualsiasi dei suoi discendenti riceve il focus.

Vantaggi:

  • Migliore UX/Accessibilità per Form: Evidenziare l’intero gruppo di campi (<div>, <fieldset>) a cui l’utente sta lavorando migliora la navigazione e l’accessibilità, specialmente in form complessi.
  • Styling di Componenti Interattivi: Utilissimo per stilizzare componenti come dropdown, modali o menu che contengono elementi focizzabili, senza dover gestire lo stato del focus con JavaScript.
  • CSS Puro: Permette di ottenere effetti di evidenziazione o cambiamento di stile sul contenitore basati sull’interazione dell’utente, utilizzando solo CSS.

Esempio Pratico:

Vogliamo che un gruppo di input all’interno di un form (.form-group) cambi sfondo quando l’utente interagisce con uno qualsiasi degli input, select o textarea al suo interno.

<form>
    <div class="form-group">
        <label for="nome">Nome:</label>
        <input type="text" id="nome">
    </div>

    <div class="form-group">
        <label for="messaggio">Messaggio:</label>
        <textarea id="messaggio"></textarea>
    </div>

    <div class="form-group">
        <label for="paese">Paese:</label>
        <select id="paese">
            <option value="it">Italia</option>
            <option value="ch">Svizzera</option>
        </select>
    </div>
</form>

CSS con :focus-within:

.form-group {
    border: 1px solid #ccc;
    padding: 1em;
    margin-bottom: 1em;
    border-radius: 5px;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

/* Quando un elemento focizzabile all'interno di .form-group è attivo */
.form-group:focus-within {
    background-color: #f0f0f0;
    border-color: blue;
}

/* Opzionale: stile base per gli input al focus per coerenza */
input:focus,
textarea:focus,
select:focus {
    outline: none; /* Rimuovi l'outline di default se non lo vuoi */
    box-shadow: 0 0 5px rgba(0, 100, 255, 0.5);
}

Questo semplice esempio mostra quanto sia facile migliorare l’esperienza utente di un form utilizzando :focus-within per fornire un feedback visivo chiaro su quale sezione del form l’utente stia attualmente modificando. È un selettore potentissimo per l’usabilità che merita molta più attenzione.

5. ::marker: Stilizzare i Marker delle Liste Facilmente

Le liste (<ul>, <ol>) sono elementi HTML fondamentali, ma stilizzare i loro “marker” (i pallini o i numeri) è sempre stato un po’ macchinoso, spesso richiedendo la rimozione del marker nativo (list-style: none) e l’uso di ::before o ::after per ricrearne uno personalizzato. Il pseudo-elemento ::marker semplifica notevolmente questo processo.

Spiegazione:

Il pseudo-elemento ::marker seleziona il box del marker (il pallino, il numero, la lettera, ecc.) di un elemento lista (<li>). Permette di stilizzare direttamente alcune proprietà di questo marker.

Vantaggi:

  • Stilizzazione Semplice: Cambiare colore, dimensione o contenuto base del marker diventa diretto.
  • Nativo: Utilizza il meccanismo nativo del browser per i marker, potenzialmente con una gestione migliore dell’allineamento rispetto a soluzioni basate su pseudo-elementi custom.
  • Meno Codice: Evita l’hack di nascondere il marker nativo e crearne uno fittizio con ::before.

Esempio Pratico:

Vogliamo cambiare il colore e la dimensione dei pallini in una lista non ordinata e cambiare colore e tipo di font per i numeri in una lista ordinata.

<h2>Lista Non Ordinata</h2>
<ul>
    <li>Elemento uno</li>
    <li>Elemento due</li>
    <li>Elemento tre</li>
</ul>

<h2>Lista Ordinata</h2>
<ol>
    <li>Primo elemento</li>
    <li>Secondo elemento</li>
    <li>Terzo elemento</li>
</ol>

CSS con ::marker:

/* Stile per i pallini della lista non ordinata */
ul li::marker {
    color: purple; /* Cambia colore */
    font-size: 1.2em; /* Cambia dimensione (limitato) */
    /* content: '👉 '; */ /* Puoi anche cambiare il contenuto del marker (limitato) */
}

/* Stile per i numeri della lista ordinata */
ol li::marker {
    color: green; /* Cambia colore */
    font-weight: bold; /* Cambia peso del font */
    /* font-feature-settings: "tnum"; */ /* Esempi di altre proprietà limitate */
    /* Non tutte le proprietà font/text funzionano */
}

Sebbene le proprietà stilizzabili con ::marker siano ancora limitate rispetto a un ::before (non potete controllare liberamente posizionamento, padding, margin, box-shadow, ecc.), per modifiche semplici come colore, dimensione font base o contenuto, è uno strumento molto più pulito e semantico dell’approccio tradizionale. È un altro esempio di selettore CSS meno conosciuto che semplifica compiti comuni. Potete approfondire la tipografia web per capire meglio come questi dettagli influenzano l’esperienza utente (Link interno: Tipografia web: come scegliere e ottimizzare i font).


Quando e Come Utilizzare Questi Selettori nei Progetti Moderni

Abbiamo esplorato 5 selettori CSS meno conosciuti ma estremamente potenti. Ma come integrarli efficacemente nei vostri progetti moderni?

  1. Valutate la Compatibilità Browser: Prima di usare un selettore avanzato in produzione, controllate sempre il suo supporto sui browser che dovete supportare (ad esempio, su caniuse.com). :is(), :where(), i selettori di attributo avanzati e ::marker hanno un ottimo supporto oggi. :has() ha visto un miglioramento significativo di recente ed è utilizzabile in molti scenari, ma potrebbe richiedere fallback per browser molto vecchi.
  2. Pulizia del Codice: Usate :is() e :where() per consolidare regole ripetitive e rendere il vostro codice base più leggibile e modulare. Scegliete tra i due in base alle vostre esigenze di specificità.
  3. UX e Accessibilità: Sfruttate :focus-within per migliorare l’usabilità e l’accessibilità dei form e dei componenti interattivi, fornendo feedback visivi chiari all’utente. Integrate :has() per stati complessi basati sul contenuto.
  4. Riduzione del JavaScript: Molti effetti e interazioni che in passato richiedevano l’aggiunta/rimozione di classi via JavaScript possono ora essere gestiti interamente con CSS, grazie a selettori come :has() e :focus-within. Questo porta a un codice più leggero e un’esperienza utente più reattiva.
  5. Semanticità e Mantenibilità: Utilizzate i selettori di attributo avanzati per agganciare stili a elementi basandovi sui loro attributi nativi (href, alt, data-*), riducendo la necessità di classi helper puramente stilistiche. Questo rende il vostro HTML più pulito e il CSS più strettamente legato alla struttura semantica.
  6. Stilizzazione Fini: ::marker vi offre un controllo più granulare e pulito sui marker delle liste rispetto ai vecchi hack con ::before.
  7. Combinazione: Il vero potere emerge spesso combinando questi selettori tra loro o con selettori più comuni. Ad esempio, :is(.card):has(img) vi permette di selezionare card che sono anche .card e contengono un’immagine.

Integrare questi selettori CSS meno conosciuti nella vostra pratica quotidiana richiede un po’ di sperimentazione, ma i benefici in termini di pulizia del codice, mantenibilità e potenza espressiva sono enormi. Per approfondire ulteriormente le tecniche di styling moderno, potete leggere la nostra Guida CSS Avanzato 2025 o scoprire Trucchi CSS avanzati per velocizzare lo sviluppo frontend. Anche una buona Checklist SEO tecnica per sviluppatori frontend vi ricorderà l’importanza di un CSS ben strutturato e performante.

Conclusione

Il CSS è un linguaggio in continua evoluzione, e padroneggiare i suoi strumenti meno ovvi è ciò che distingue un buon frontend developer. I selettori CSS meno conosciuti che abbiamo esplorato – :is(), :where(), :has(), i selettori di attributo avanzati e ::marker – sono solo la punta dell’iceberg, ma rappresentano un salto di qualità notevole nel modo in cui possiamo scrivere stili.

Vi incoraggio a sperimentare con questi selettori nei vostri prossimi progetti. Iniziate con piccoli esperimenti, consultate sempre la documentazione ufficiale (MDN Web Docs è una risorsa eccellente per ogni selettore menzionato) e verificate la compatibilità browser. Scoprirete presto come possono aiutarvi a scrivere CSS più efficiente, pulito e potente.

Il viaggio nel CSS avanzato non finisce qui. Ci sono molti altri concetti e strumenti da esplorare, come spiegato nella nostra guida CSS Grid vs Flexbox: Quando Usare Cosa o negli articoli sugli Effetti hover CSS. Continuate a studiare e a sperimentare, e vedrete le vostre capacità di styling raggiungere nuovi livelli.

Quali di questi selettori usate già? Quale trovate più utile o sorprendente? Fatecelo sapere nei commenti!

Condividi

Articoli Recenti

Categorie popolari