Frontend

Selettori avanzati in CSS

Autore

Manuel Ricci

Quando parlo di selettori avanzati in CSS in realtà parlo dei selettori più moderni, quelli che sono stati adottati da poco, ma che comunque già si sono distinti per capacità di selezione.

In questa lezione vedremo quindi dei selettori che ci permetteranno di:

  • Selezionare tutti i link con un attributo href
  • Selezionare elementi vuoti
  • Escludere dalla selezione
  • Selezionare genitori dei discendenti
  • Selezionare l’elemento in focus con decisione euristica sulla visualizzazione dello stato
  • Selezionare l’elemento con un discendente in stato di focus

In più vedremo come semplificare alcuni selettori con l’ausilio di un paio di nuove pseudo-classi

Questo può sembrare il più inutile tra tutti perché abbiamo altri modi per poter selezionare i link con un attributo href, come ad esempio a[href], ma :any-link serve principalmente a selezionare quei tag <a> che hanno l’attributo href impostato sia che siano stati visitati oppure no. Cosa che altrimenti avremmo dovuto fare con due selettori pseudo classi separate :link e :visited.

Occhio di riguardo va comunque alla specificità, :any-link in qualità di pseudo classe ha specificità 10, mentre il selettore a vale solo 1.

1\:any-link {
2   color: red;
3}
4
5a {
6   color: blue;
7}

Il colore del link sarà rosso per via della specificità.

Selezionare elementi vuoti con :emtpy

Questa pseudo classe è sempre stata molto utile. Da quando è stata introdotta non ho potuto più farne a meno. Può capitare che in pagina ci siano degli elementi non nascosti (con display: none, visibility: hidden o altri metodi) alla quale però il browser computa dei margini (es. i paragrafi).

Quindi nonostante non ci sia nulla, gli elementi sono visibilmente più in basso per colpa di questi elementi nascosti.

In questi casi entra in gioco :empty il quale ci permette di assegnare degli stili a questi elementi specifici.

1p:empty {
2   margin: 0;
3}

Escludere dalla selezione con :not()

:not() è una pseudo classe che è stata notevolmente potenziata. Permette in sostanza di escludere uno o più elementi dalla selezione. Un esempio molto chiaro è questo:

1<ul>
2   <li>...</li>
3   <li>...</li>
4   <li>...</li>
5</ul>

Vogliamo dare uno stile a tutti tranne all’ultimo, senza :not() si fa così:

1li {
2   border-bottom: 1px solid #ccc
3}
4
5li:last-child {
6   border-bottom: 0
7}

Con :not() il discorso è diverso:

1li:not(:last-child) {
2   border-bottom: 1px solid #ccc
3}

Decisamente più semplice.

Uno degli ultimi aggiornamenti subiti da :not() è che ora tra parentesi possiamo dichiarare più elementi separati da virgola, mentre prima era necessario concatenare più :not().

Selezionare i genitori di un elemento discendente

Questo è in assoluto il mio preferito. Per tantissimi anni ho insegnato CSS spiegando che non c’era modo di risalire al genitore e invece ora grazie a :has() questo è possibile.

Ipotizziamo di avere questo HTML:

1<article class=”guida”>
2   <h2>Lorem ipsum</h2>
3   <h3>dolor sit amet</h3>
4</article>
5<article class=”guida”>
6   <h2>Lorem ipsum</h2>
7</article>

I nostri article contengono un h2 e opzionalmente un h3, sappiamo come selezionare h3 perché basta usare il combinatore di fratello adiacente + in questo modo h2 + h3, ma lo stile si applica ad h3 e non ad h2, come facciamo a fare il contrario? Con :has(), in questo modo h2:has(+ h3) e gli stili verranno applicati ad h2. Meraviglioso.

Menzione d’onore: focus-within e focus-visible

Già discussi durante la prima lezione sui selettori anche :focus-within e :focus-visible fanno parte di questi selettori e giusto un piccolo ripassino:

  • :focus-within: permette di selezionare un elemento che ha un discendente che è in stato di :focus
  • :focus-visible: permette di selezionare un elemento in stato di :focus, ma sarà il browser a determinare euristicamente se far vedere visivamente lo stato.

Pseudo classi per semplificare i selettori

Ci sono ancora due pseudo classi molto interessanti in CSS che sono :is() e :where(), supponiamo di avere un selettore del genere:

1h1 > b, h2 > b, h3 > b, h4 > b, h5 > b, h6 > b {}

Con :is() possiamo semplificarlo come segue:

1\:is(h1,h2,h3,h4,h5,h6) > b {}

:is() ci permette quindi di raggruppare i selettori, semplificando notevolmente la scrittura. Mentre :where() che fa? La stessa identica cosa di :is(), ma c’è solo una importantissima differenza. La specificità.

:is() avrà la specificità corrispondente al selettore più importante del gruppo, mentre per :where() sarà sempre 0.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.