Corso di CSS / Stati dei moduli CSS: focus, validazione, disabled e readonly

Il CSS può stilizzare focus, validità e controlli modulo disabilitati o di sola lettura, ma l'HTML definisce le loro etichette, vincoli e comportamento di invio. :invalid può corrispondere prima dell'interazione, mentre :user-invalid aiuta a ritardare lo stile degli errori fino a quando il browser lo ritiene appropriato.

Associa etichette e istruzioni ai controlli

Se il valore dell’attributo for di label e l'ID della finestra di input coincidono, il nome dell'elemento e la finestra di input sono collegati. I segnaposto scompaiono una volta che inizi a digitare, quindi non sostituiscono i nomi o condizioni importanti. Per spiegazioni aggiuntive, lascia la frase visibile e specifica l'ID della frase in aria-describedby.

<label for="email">Email address (required)</label>
<input id="email" name="email" type="email" required
  placeholder="name@example.com" aria-describedby="email-help">
<p id="email-help">Enter name@example.com in the same format.</p>

Il codice parziale sopra rappresenta brevemente la sezione email dell'esempio completo qui sotto. id identifica l'oggetto nel documento, e name è il nome dell'elemento nei dati inviati. Se name non è presente, non sarà incluso nei normali invii del modulo, anche se puoi digitarlo sullo schermo. Per la composizione di etichette e descrizioni, fare riferimento a Guida alle etichette dei moduli W3C e Guida all'input dei moduli.

Dimensionare i controlli per schermi stretti e testo ingrandito

Se ti affidi solo alla larghezza intrinseca della finestra di input, potrebbe superare lo schermo stretto quando la dimensione del carattere viene aumentata. Imposta la larghezza massima del modulo e utilizza width: 100% e box-sizing: border-box insieme nella finestra di input. Questo garantirà che anche il bordo e il padding siano inclusi nella larghezza specificata.

*, *::before, *::after { box-sizing: border-box; }
form { max-width: 28rem; }
input { width: 100%; min-width: 0; padding: .65rem; font: inherit; }

Questa regola è inclusa nella sezione stile dell'intero esempio. font: inherit permette alla finestra di input e ai pulsanti di seguire il font, la dimensione e l'altezza della linea del testo, e min-width: 0 consente al controllo di restringersi anche quando si inserisce la finestra di input in un Flexbox/Grid. Non viene utilizzata un'altezza fissa in modo che gli elementi sottostanti si spostino naturalmente verso il basso anche quando la descrizione viene aumentata o le lettere ingrandite.

Separare lo stato di focus e gli errori di validazione

:focus corrisponde all'elemento che attualmente ha il focus, e :focus-visible corrisponde se il browser determina che è necessario mostrare il focus. Viene principalmente visualizzato durante la navigazione tramite tastiera, ma può anche essere visualizzato cliccando con il mouse nella finestra di input del testo, quindi non dovrebbe essere inteso come “applicabile solo alla tastiera.” MDN: :focus-visible e criteri del browser . Per applicare in modo coerente l'indicazione del focus anche ai link, confrontare Stati dei link e focus visibile da tastiera.

Il focus indica l'elemento che stai attualmente manipolando, e gli errori indicano gli elementi che non hanno soddisfatto le condizioni di input. Poiché entrambi gli stati possono essere presenti contemporaneamente, l'intero esempio mostra il focus con un contorno blu e l'errore con un bordo rosso scuro e una dichiarazione di errore. Lasciare un po' di spazio intorno al contorno per evitare di troncarlo e evitare di rimuovere il contorno senza fornire un altro indicatore di focus.

:invalid corrisponde se il valore attuale è non valido, quindi anche un campo obbligatorio vuoto viene corrisposto fin dall'inizio. :user-invalid corrisponde quando il browser mostrerà una condizione di errore dopo l'interazione dell'utente. Quando viene visualizzato qualcosa, ad esempio al termine della digitazione o al tentativo di invio, può dipendere dal comportamento del tuo browser. Il laboratorio verifica gli errori premendo il pulsante Invia. MDN: :user-invalid .

Se è necessario considerare obiettivi di supporto più datati, è necessario verificare se il selettore è supportato e progettare un flusso di verifica separato. Anche se la decorazione degli errori non appare perché il selettore non è supportato, ciò non significa che i controlli obbligatori e di formattazione di HTML scompaiano. Scegli un colore di focus sufficientemente distinto dallo sfondo reale, e verifica anche le condizioni di applicazione della Guida W3C al Contrasto Non Testuale.

Confronta richiesto, valido, disabilitato e sola lettura

situazione significato Focus e invio generale
required L'utente deve inserire un valore Può ricevere il focus se l'elemento è attivo; I valori vuoti sono soggetti a convalida al momento dell'invio
:valid·:invalid Se le condizioni di convalida HTML sono soddisfatte I risultati della verifica sono determinati indipendentemente dalla forma del bordo
disabled Attualmente non disponibile Tipicamente escluso dalla navigazione con tab e dagli invii
readonly Impossibile modificare valori come l'input di testo supportato Può ricevere il focus ed essere selezionato; Se esiste un nome, includilo nell'invio

readonly è supportato da controlli particolari simili a testi e non è un modo generale per rendere un elemento select di sola lettura. I controlli di sola lettura supportati sono esclusi dalla convalida dei vincoli, mentre i controlli nominati possono comunque inviare dati del modulo. Distinguere questo comportamento dai controlli disabilitati. Vedere HTML Standard: costruzione dell'elenco di inserimento, MDN: readonly.

Questo campo email dimostra un formato come name@example.com. Superare il controllo di validità non conferma che l'account esista o possa ricevere posta. La validazione HTML type="email" non accetta tutti i formati di indirizzi internazionalizzati; le parti locali non ASCII non sono presentate qui come input garantito valido. Per ulteriori dettagli, vedere Condizioni standard HTML per l'input email.

Esegui l'esempio e controlla i campi inviati

Salva il codice seguente come form-states.html in UTF-8 e aprilo nel tuo browser. HTML e CSS determinano lo stato del modulo. Il piccolo pezzo di JavaScript alla fine è codice ausiliario per intercettare gli invii validi e mostrare una lista di dati sullo schermo, senza inviarli al server o eseguire ulteriori controlli sull'input. Se JavaScript è disattivato, la funzione di output dei risultati non funzionerà.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Comparing form states and submitted fields</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
form { max-width: 28rem; }
.field { margin-block: 1.25rem; }
label { display: block; margin-bottom: .35rem; font-weight: 700; }
input { display: block; width: 100%; min-width: 0; padding: .65rem;
  border: 2px solid #6d7e8b; border-radius: .3rem; background: white; color: #183044; }
input:required { border-inline-start-width: 4px; }
input:user-invalid { border-color: #9d2632; }
.help, .error { margin-block: .4rem 0; }
.error { display: none; color: #9d2632; }
input:user-invalid + .error { display: block; }
input[readonly] { background: #eef6fa; }
input:disabled { background: #eceff2; color: #465766; cursor: not-allowed; }
button { padding: .65rem 1rem; border: 1px solid #164f73; border-radius: .3rem;
  background: #166b92; color: white; }
output { display: block; margin-block: 1rem; white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
<main>
<h1>Check input states and submitted data</h1>
<form id="demo-form">
  <div class="field">
    <label for="email">Email address (required)</label>
    <input id="email" name="email" type="email" autocomplete="email" required
      placeholder="name@example.com" aria-describedby="email-help email-error">
    <p id="email-error" class="error">Enter an email address in a format such as name@example.com; do not leave the field empty.</p>
    <p id="email-help" class="help">This sample input checks the address format. It does not check whether the example address receives mail.</p>
  </div>
  <div class="field">
    <label for="plan">Plan (read-only)</label>
    <input id="plan" name="plan" type="text" value="Basic" readonly>
  </div>
  <div class="field">
    <label for="coupon">Coupon (currently disabled)</label>
    <input id="coupon" name="coupon" type="text" value="WELCOME" disabled>
  </div>
  <button type="submit">Check submitted fields</button>
</form>
<output id="result" for="email plan coupon" aria-live="polite"></output>
<script>
  const form = document.getElementById("demo-form");
  form.addEventListener("submit", (event) => {
    event.preventDefault();
    const entries = Array.from(new FormData(form).entries());
    document.getElementById("result").textContent = JSON.stringify(entries, null, 2);
  });
</script>
</main>
</body>
</html>
  1. Lascia vuoto il tuo indirizzo email e premi il pulsante Check submitted fields. Controlla nel tuo browser le istruzioni per l'input richiesto e i messaggi di errore.
  2. Inserisci abc nell'email e reinvia. Una nuova lista di risultati non dovrebbe essere mostrata a causa di un errore di formato.
  3. Inserisci name@example.com e invia. I risultati includono email e plan, ma non c'è nessun coupon disabilitato.
  4. Usa il tasto Tab per navigare su Email → Plan → Check submitted fields. I coupon inattivi vengono ignorati nell'ordine normale di tabulazione e i piani solo lettura possono ricevere il focus.
  5. In tutto l'esempio, rimuovi soltanto l’attributo disabled dal campo Coupon. Il campo Coupon diventa raggiungibile con Tab e il suo valore WELCOME compare nei risultati di un invio valido. Dopo la conferma, ripristina disabled.
  6. Rimuovi solo l'attributo readonly del piano e prova a modificarlo. Dopo il confronto, ripristina il suo valore su “Basic” e aggiungi di nuovo readonly.
  7. Riduci la larghezza dello schermo e regola l'ingrandimento del browser o le impostazioni della dimensione del carattere. Verifica che la finestra di input, il contorno del focus e le frasi di errore non siano tagliati o sovrapposti.

Comprendere i limiti di CSS e della convalida del browser

CSS è responsabile della visualizzazione dello stato di un elemento. La verifica del browser può ridurre gli errori di input dell'utente, ma può essere bypassata con strumenti per sviluppatori o richieste separate, quindi il servizio effettivo deve ricontrollare sul server i valori consentiti, la lunghezza, i permessi, ecc. Le frasi di errore descrivono specificamente gli elementi problematici e le soluzioni, ed è progettato anche un flusso separato per preservare le informazioni di input quando si verifica un errore del server.

Se l'esempio si comporta in modo imprevisto, controllare prima le coppie label for/input id, i nomi dei moduli inviati, i campi obbligatori, i tipi di input e gli stati disabilitati o readonly. Se il focus è invisibile, verificare se un'altra regola outline lo sovrascrive. Gli errori mostrati immediatamente possono derivare da :invalid. Se il messaggio rimane nascosto dopo un tentativo di invio, verifica il supporto di :user-invalid e la lezione sui combinatori e sulle pseudo-classi CSS.