W3docs

CSS :invalid Pseudo Classe

Scopri come CSS :invalid stila i campi modulo che non superano i vincoli di validazione, con esempi, avvertenze, consigli sull'accessibilità e supporto browser.

La pseudo-classe CSS :invalid corrisponde ai controlli associati ai moduli — come <input>, <select> e <textarea> — il cui valore corrente non supera i vincoli di validazione integrati nel browser. È la parte visiva dell'API di validazione dei vincoli di HTML: il browser valuta la validità e :invalid ti consente di stilizzare il risultato con puro CSS, senza JavaScript.

Questa pagina copre esattamente quando :invalid corrisponde, come stilizzarlo senza allertare gli utenti prima che abbiano digitato qualcosa, la particolarità dei pulsanti radio, l'alternativa moderna :user-invalid e come mantenere il feedback degli errori accessibile.

Quando un elemento corrisponde a :invalid?

Un controllo corrisponde a :invalid quando porta almeno un vincolo di validazione e il suo valore corrente viola quel vincolo. Trigger comuni:

VincoloAttributo / tipoFallisce quando…
Obbligatorio ma vuotorequiredil campo non ha valore
Formato email erratotype="email"il valore non è un'e-mail sintatticamente valida
Formato URL erratotype="url"il valore non è un URL assoluto valido
Fuori dall'intervallomin / max su type="number", type="date", ecc.il valore è al di fuori dell'intervallo consentito
Step erratostepil valore non si allinea con l'intervallo dello step
Mancata corrispondenza del patternpatternil valore non corrisponde alla regex
Troppo lungo / troppo cortominlength / maxlengthla lunghezza del valore è al di fuori dell'intervallo consentito

Se un controllo non ha vincoli (un semplice <input type="text"> senza attributi aggiuntivi), viene considerato senza vincoli e né :valid:invalid si applicano ad esso.

Un elemento <fieldset> corrisponde a :invalid quando uno qualsiasi dei suoi controlli modulo discendenti non è valido.

Per il lato opposto, vedi la pseudo-classe :valid, che corrisponde ai controlli che superano tutti i vincoli. La pseudo-classe :required corrisponde ai campi obbligatori indipendentemente dal fatto che abbiano un valore.

Sintassi

:invalid {
  /* declarations applied to all invalid form controls */
}

Limita :invalid a un tipo di elemento specifico per mantenere gli stili prevedibili:

input:invalid,
textarea:invalid {
  border: 2px solid #c00;
  outline: none;
}

Esempio di base

Il campo email qui sotto è pre-compilato con un indirizzo non valido ("not-an-email"), quindi corrisponde a input:invalid al caricamento e ottiene un bordo rosso.

<!DOCTYPE html>
<html>
  <head>
    <title>:invalid example</title>
    <style>
      input:invalid {
        border: 2px solid #c00;
        background-color: #fff0f0;
      }
      input:valid {
        border: 2px solid #090;
        background-color: #f0fff0;
      }
    </style>
  </head>
  <body>
    <h2>:invalid selector example</h2>
    <form>
      <label for="email">Email:</label>
      <input id="email" type="email" value="not-an-email" required />
    </form>
  </body>
</html>

Evitare il "rosso prematuro"

Il problema più comune con :invalid: un campo required vuoto è già non valido nel momento in cui la pagina si carica, quindi un modulo appena aperto può diventare rosso prima che l'utente abbia digitato qualcosa. Questo risulta accusatorio.

Opzione 1 — stilizza solo quando il campo è attivo

Mostra il bordo di errore solo mentre l'utente è attivamente nel campo:

input:invalid:focus {
  border-color: #c00;
  outline: 2px solid #c00;
  outline-offset: 1px;
}

Questo è semplice ma scompare nel momento in cui l'utente passa al campo successivo con Tab, quindi un campo obbligatorio vuoto sembra di nuovo a posto.

Opzione 2 — nascondi l'errore mentre il placeholder è visibile

:placeholder-shown è vero quando il testo placeholder è visualizzato (cioè il campo è vuoto). Combinandolo con :not, lo stile di :invalid si attiva solo quando l'utente ha digitato qualcosa:

/* Only show the error style when the field has a value that is invalid */
input:invalid:not(:placeholder-shown) {
  border-color: #c00;
}

Questo è efficace ma richiede che ogni campo abbia un attributo placeholder impostato — altrimenti :placeholder-shown non è mai vero e la guardia non fa nulla.

Opzione 3 — usa :user-invalid (standard moderno)

La pseudo-classe :user-invalid è stata progettata specificamente per risolvere questo problema. Si comporta come :invalid ma corrisponde solo dopo che l'utente ha interagito con il controllo (digitato, deselezionato o inviato il modulo):

/* Supported in all modern browsers as of 2024 */
input:user-invalid {
  border-color: #c00;
}

/* Fallback for older browsers */
@supports not selector(:user-invalid) {
  input:invalid:not(:placeholder-shown) {
    border-color: #c00;
  }
}

:user-invalid è la soluzione più pulita quando puoi farci affidamento. Firefox la supporta da anni come :-moz-ui-invalid; lo standard :user-invalid è ora disponibile in tutti i browser moderni.

Approccio allo stile

Un bordo pieno severo di 2 px rosso è leggibile ma stridente. Considera di combinare un cambiamento del bordo con un sottile box-shadow per un aspetto più morbido:

input:invalid:not(:placeholder-shown) {
  border-color: #c00;
  box-shadow: 0 0 0 3px rgba(204, 0, 0, 0.15);
}

Evita di affidarti solo al colore — vedi la sezione Accessibilità di seguito.

Avvertenze

Pulsanti radio

Quando un gruppo di pulsanti radio ha required su uno degli input, ogni pulsante del gruppo corrisponde a :invalid mentre nessuno è selezionato. Stilizzare piccoli cerchi radio non è pratico; invece, stilizza il <fieldset> circostante o il <label>:

/* Style the fieldset, not the radio buttons themselves */
fieldset:invalid {
  border: 2px solid #c00;
  border-radius: 4px;
  padding: 8px 12px;
}

Tutti i pulsanti radio in un gruppo condividono lo stesso attributo name — è questo che li rende un gruppo nel modello di validità del browser.

Campi opzionali vuoti

Un semplice <input type="text"> senza required, senza pattern e senza vincoli di lunghezza è sempre :valid anche quando è vuoto. :invalid si attiva solo quando esiste un vincolo ed è violato.

select e textarea

<select> corrisponde a :invalid se è required e il suo value corrente è una stringa vuota (un pattern comune è un'opzione segnaposto "-- scegli --" <option value=""> in cima). <textarea> segue le stesse regole di <input> per required, minlength e maxlength.

Firefox e :-moz-ui-invalid

Firefox ha a lungo applicato stili tramite :-moz-ui-invalid, che si attiva solo dopo l'interazione dell'utente — in pratica il comportamento di :user-invalid integrato. Se aggiungi le tue regole :invalid e le testi in Firefox, il campo potrebbe sembrare a posto (perché la guardia predefinita per l'interazione dell'utente del browser è attiva), poi comportarsi diversamente in Chrome (dove la guardia predefinita è disattivata). Definisci regole esplicite e usa :user-invalid con un fallback per ottenere un comportamento coerente.

Accessibilità

Il colore da solo non è mai sufficiente per comunicare un errore — gli utenti con deficit nella percezione dei colori potrebbero non percepire un bordo rosso. Abbina lo stile di :invalid con:

  • Un messaggio di testo visibile che spieghi cosa è andato storto e come correggerlo.
  • Un'icona o un simbolo accanto al cambiamento di colore (ad es., una ✕ o un'icona di avviso).
  • aria-invalid="true" sul controllo in modo che i lettori di schermo lo annuncino come non valido.
  • aria-describedby che punta all'elemento del messaggio di errore in modo che la descrizione venga letta automaticamente.
<label for="email">Email address</label>
<input
  id="email"
  type="email"
  aria-invalid="true"
  aria-describedby="email-error"
  required
/>
<span id="email-error" role="alert">
  Please enter a valid email address.
</span>

Il role="alert" sullo span dell'errore fa sì che i lettori di schermo annuncino il messaggio non appena appare nel DOM, anche senza focus.

Pseudo-classi correlate

Pseudo-classeCorrisponde quando…
:validil controllo supera tutti i suoi vincoli
:requiredil controllo ha l'attributo required
:optionalil controllo non ha required
:out-of-rangeil valore di un input numerico/data supera min/max
:in-rangeil valore di un input numerico/data è compreso tra min/max
:placeholderil testo placeholder di un input
:focusil controllo ha attualmente il focus da tastiera

Supporto browser

:invalid fa parte di Selectors Level 4 ed è supportato in tutti i principali browser da molti anni. :user-invalid (la variante consapevole dell'interazione) è disponibile a partire da Chrome 119, Firefox 88 (come :-moz-ui-invalid molto prima), e Safari 16.5.

Per ulteriori informazioni sugli attributi di vincolo nativi di HTML, vedi <input> e HTML Forms.

Pratica

Pratica
Qual è la funzione della pseudo-classe ':invalid' in CSS?
Qual è la funzione della pseudo-classe ':invalid' in CSS?
Was this page helpful?