Podcast su CSS - 015: Pseudo-classi
Supponiamo che tu abbia un modulo di iscrizione
email e voglia che il campo del modulo email abbia un bordo rosso se contiene un indirizzo email non valido.
E come potete farlo?
Puoi utilizzare una pseudo-classe CSS :invalid
,
che è una delle numerose pseudo-classi fornite dal browser.
Una pseudo-classe consente di applicare gli stili in base alle modifiche di stato e a fattori esterni. Ciò significa che il tuo design può reagire all'input dell'utente, ad esempio a un indirizzo email non valido. Questi vengono esaminati nel modulo Selettori e in questo modulo li guideremo in modo più dettagliato.
A differenza degli pseudo-elementi, di cui puoi scoprire di più nel modulo precedente, le pseudoclassi si connettono a specifici stati in cui potrebbe trovarsi un elemento, piuttosto che in generale definire le parti di quell'elemento.
Stati interattivi
Le seguenti pseudo-classi si applicano a causa di un'interazione che un utente ha con la tua pagina.
:hover
Se un utente ha un dispositivo di puntamento come un mouse o un trackpad e lo posiziona sopra un elemento, puoi agganciarti a quello stato con :hover
per applicare gli stili.
È un modo utile per suggerire la possibilità di interagire con un elemento.
:active
Questo stato viene attivato quando un elemento è attivamente in fase di interazione, ad esempio un clic, prima che il clic venga rilasciato. Se utilizzi un dispositivo di puntamento come un mouse, questo stato indica l'avvio del clic e non è ancora stato rilasciato.
:focus
, :focus-within
e :focus-visible
Se un elemento può essere impostato come attivo, come <button>
,
puoi reagire a quello stato con la pseudo-classe
:focus
.
Puoi anche reagire se un elemento secondario dell'elemento viene evidenziato con :focus-within
.
Gli elementi per cui è possibile impostare lo stato attivo, come i pulsanti, mostrano un anello di messa a fuoco quando sono a fuoco, anche se selezionati. In questo tipo di situazione, uno sviluppatore applicherà il seguente CSS:
button:focus {
outline: none;
}
Questo CSS rimuove l'anello di attivazione predefinito del browser quando viene attivato un elemento, il che crea un problema di accessibilità per gli utenti che navigano in una pagina web usando la tastiera.
Se non è presente uno stile di impostazione dello stato attivo, non saranno in grado di tenere traccia dell'area in cui si trova attualmente lo stato attivo quando viene usato il tasto Tab.
Con :focus-visible
puoi presentare uno stile di impostazione dello stato attivo quando un elemento è impostato come attivo tramite la tastiera e, al contempo, utilizzare la regola outline: none
per impedire l'interazione con un dispositivo di puntamento.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
La pseudo-classe :target
seleziona un elemento con un id
corrispondente a un frammento URL.
Supponi di avere il seguente codice HTML:
<article id="content">
…
</article>
Puoi associare gli stili a quell'elemento quando l'URL contiene #content
.
#content:target {
background: yellow;
}
È utile per evidenziare tramite uno skip link le aree che potrebbero essere state collegate in modo specifico, come i contenuti principali di un sito web.
Stati storici
:link
La pseudo-classe :link
può essere applicata a qualsiasi elemento <a>
che abbia un valore href
che non è ancora stato visitato.
:visited
Puoi definire uno stile per un link già visitato dall'utente utilizzando la pseudo-classe :visited
.
Questo è lo stato opposto di :link
, ma hai meno proprietà CSS da utilizzare per
motivi di sicurezza.
Puoi applicare uno stile solo a color
, background-color
, border-color
, outline-color
e al colore SVG fill
e stroke
.
L'ordine conta
Se definisci uno stile :visited
,
può essere sostituito da una pseudo-classe di link con almeno la stessa specificità.
Per questo motivo, ti consigliamo di utilizzare la regola LVHA per assegnare uno stile ai link con pseudo-classi in un determinato ordine: :link
, :visited
, :hover
, :active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
Stati del modulo
Le seguenti pseudo-classi possono selezionare gli elementi del modulo, nei vari stati in cui questi elementi potrebbero trovarsi durante l'interazione.
:disabled
e :enabled
Se un elemento del modulo, ad esempio <button>
, viene disattivato dal browser, puoi agganciarti a quello stato con la pseudo-classe :disabled
.
La pseudo-classe :enabled
è disponibile per lo stato opposto,
sebbene anche gli elementi del modulo siano :enabled
per impostazione predefinita,
quindi potresti non trovarti a raggiungere questa pseudo-classe.
:checked
e :indeterminate
La pseudo-classe :checked
è disponibile quando un elemento modulo di supporto, come una casella di controllo o un pulsante di opzione, è selezionato.
Lo stato :checked
è uno stato binario(true o false),
ma le caselle di controllo hanno uno stato intermedio quando non sono né selezionate né deselezionate.
Questo è noto come stato :indeterminate
.
Un esempio di questo stato è l'uso del controllo "Seleziona tutto" che seleziona tutte le caselle di controllo di un gruppo. Se l'utente deselezionasse una di queste caselle di controllo, la casella di controllo principale non rappresenterà più la selezione di "tutte", pertanto dovrebbe essere in uno stato indeterminato.
L'elemento <progress>
ha anche uno stato indeterminato a cui è possibile applicare uno stile.
Un caso d'uso comune è dargli un aspetto a righe per indicare che non è noto quanto altro sia necessario.
:placeholder-shown
Se un campo del modulo ha un attributo placeholder
e nessun valore,
la pseudo-classe :placeholder-shown
può essere utilizzata per collegare gli stili a quello stato.
Non appena sono presenti contenuti sul campo, indipendentemente dal fatto che abbiano o meno placeholder
, questo stato non verrà più applicato.
Stati di convalida
Puoi rispondere alla convalida del modulo HTML con pseudo-classi come
:valid
,
:invalid
e
:in-range
.
Le pseudo-classi :valid
e :invalid
sono utili per contesti come un campo email con un pattern
che deve essere abbinato,
affinché sia un campo valido.
Questo stato del valore valido può essere mostrato all'utente per capire che può passare in sicurezza al campo successivo.
La pseudo-classe :in-range
è disponibile se un input ha min
e max
, ad esempio un input numerico e il valore rientra in questi limiti.
Con i moduli HTML,
puoi determinare se un campo è obbligatorio tramite l'attributo required
.
La pseudo-classe :required
sarà disponibile per i campi obbligatori.
I campi non obbligatori possono essere selezionati con la pseudo-classe :optional
.
Selezione degli elementi in base a indice, ordine e occorrenza
Esiste un gruppo di pseudo-classi che selezionano gli elementi in base alla loro posizione nel documento.
:first-child
e :last-child
Se vuoi trovare il primo o l'ultimo elemento, puoi utilizzare :first-child
e :last-child
.
Queste pseudo-classi restituiscono il primo o l'ultimo elemento di un gruppo di elementi di pari livello.
:only-child
Puoi anche selezionare elementi che non hanno elementi di pari livello,
con la pseudo-classe
:only-child
.
:first-of-type
e :last-of-type
Puoi selezionare gli elementi :first-of-type
e :last-of-type
che inizialmente sembrano avere la stessa funzione di :first-child
e :last-child
, ma tieni presente che questo codice HTML:
<div class="my-parent">
<p>A paragraph</p>
<div>A div</div>
<div>Another div</div>
</div>
E questo CSS:
.my-parent div:first-child {
color: red;
}
Nessun elemento verrebbe di colore rosso perché il primo elemento secondario è un paragrafo e non un div.
La pseudo-classe :first-of-type
è utile in questo contesto.
.my-parent div:first-of-type {
color: red;
}
Anche se il primo <div>
è il secondo elemento secondario, è ancora il primo di tipo all'interno dell'elemento .my-parent
, pertanto, con questa regola, sarà di colore rosso.
:nth-child
e :nth-of-type
Non puoi limitare i primi e gli ultimi figli e tipi.
Le pseudo-classi :nth-child
e
:nth-of-type
consentono di specificare un elemento che si trova in un determinato indice.
L'indicizzazione nei selettori CSS inizia da 1.
Puoi anche passare più di un indice in queste pseudo-classi.
Se vuoi selezionare tutti gli elementi pari, puoi utilizzare :nth-child(even)
.
Puoi anche creare selettori più complessi in grado di trovare elementi a intervalli regolari, utilizzando la microsintassi An+B.
li:nth-child(3n+3) {
background: yellow;
}
Questo selettore seleziona un terzo elemento,
a partire dal terzo.
Il valore n
in questa espressione è l'indice, che parte da zero, mentre 3 (3n
) corrisponde al valore della moltiplicazione dell'indice.
Supponiamo che tu abbia 7 <li>
elementi.
Il primo elemento selezionato è 3 perché 3n+3
si traduce in (3 * 0) + 3
.
L'iterazione successiva selezionerebbe l'elemento 6 perché n
è ora aumentato a 1
,
quindi (3 * 1) + 3)
.
Questa espressione funziona sia per :nth-child
sia per :nth-of-type
.
Puoi provare questo tipo di selettore su questo tester secondario o su questo strumento di selezione della quantità.
:only-of-type
Infine, puoi trovare l'unico elemento di un determinato tipo in un gruppo di fratelli e sorelle utilizzando :only-of-type
.
Ciò è utile se vuoi selezionare elenchi con un solo elemento o se vuoi trovare l'unico elemento in grassetto in un paragrafo.
Trovare elementi vuoti
A volte può essere utile identificare gli elementi completamente vuoti, che esiste anche una pseudo-classe.
:empty
Se un elemento non ha elementi secondari, viene applicata la pseudo-classe :empty
.
I figli non sono solo elementi HTML o nodi di testo, ma possono anche rappresentare spazi vuoti, che possono confondere quando esegui il debug del seguente codice HTML e ti chiedi perché non funziona con :empty
:
<div>
</div>
Il motivo è che sono presenti spazi vuoti tra l'elemento <div>
di apertura e quello di chiusura, pertanto il campo vuoto non funzionerà.
La pseudo-classe :empty
può essere utile se hai poco controllo sul codice HTML e vuoi nascondere elementi vuoti, ad esempio un editor di contenuti WYSIWYG.
Qui, un editor ha aggiunto un paragrafo vuoto e vagabondo.
<article class="post">
<p>Donec ullamcorper nulla non metus auctor fringilla.</p>
<p></p>
<p>Curabitur blandit tempus porttitor.</p>
</article>
Con :empty
, puoi trovare e nasconderlo.
.post :empty {
display: none;
}
Trovare ed escludere più elementi
Alcune pseudo-classi consentono di scrivere codice CSS più compatto.
:is()
Se vuoi trovare tutti gli elementi secondari h2
, li
e img
in un elemento .post
,
ti consigliamo di scrivere un elenco di selettori come il seguente:
.post h2,
.post li,
.post img {
…
}
Con la pseudo-classe :is()
, puoi scrivere una versione più compatta:
.post :is(h2, li, img) {
…
}
La pseudo-classe :is
non è solo più compatta di un elenco di selettori, ma è anche più tollerante.
Nella maggior parte dei casi,
se è presente un errore o un selettore non supportato in un elenco di selettori,
l'intero elenco di selettori non funzionerà più.
Se si verifica un errore nei selettori passati in una pseudo-classe :is
, il selettore non valido verrà ignorato, ma verranno utilizzati quelli validi.
:not()
Puoi anche escludere elementi con la pseudo-classe :not()
.
Ad esempio, puoi utilizzarlo per applicare uno stile a tutti i link che non hanno un attributo class
.
a:not([class]) {
color: blue;
}
Una pseudo-classe :not
può anche aiutarti a migliorare l'accessibilità.
Ad esempio, un <img>
deve avere un alt
, anche se è un valore vuoto,
pertanto potresti scrivere una regola CSS che aggiunga un contorno rosso spesso alle immagini non valide:
img:not([alt]) {
outline: 10px red;
}
Verifica la tua comprensione
Verifica le tue conoscenze delle pseudo classi
Le pseudo-classi agiscono come se una classe fosse stata applicata dinamicamente a un elemento, mentre gli pseudo-elementi agiscono su un elemento stesso.
:
singolo o doppio come carattere distintivo principale nel selettore.Quali delle seguenti sono una pseudo-classe funzionale?
:is()
:target
()
per indicare che accettano parametri.:empty
()
per indicare che accettano parametri.:not()
Quali delle seguenti pseudo-classi sono dovute a un'interazione utente?
:hover
:press
:squeeze
:target
:focus-within
Quali delle seguenti sono pseudoclassi di stato <form>
?
:enabled
:fresh
:indeterminate
:checked
:in-range
:loading
:valid