Devo inserire elementi di input all'interno di un elemento etichetta?


606

C'è una best practice relativa alla nidificazione di labele inputelementi HTML?

modo classico:

<label for="myinput">My Text</label>
<input type="text" id="myinput" />

o

<label for="myinput">My Text
   <input type="text" id="myinput" />
</label>

107
Uno dei grandi pro di mettere <input />dentro l' interno <label>è che puoi omettere fore id: <label>My text <input /></label>nel tuo esempio. Molto più bello!
Znarkus,

16
Anche se sono d'accordo sul fatto che inputnon appartiene semanticamente all'interno di un label, ho notato oggi che gli sviluppatori di Bootstrap non sono d'accordo con me . Alcuni elementi, come le caselle di controllo incorporate, hanno uno stile diverso a seconda che inputsia dentro o fuori.
Blazemonger,

6
A proposito, è stata una pessima idea da creare in <label for="id">quanto ho più moduli sulla pagina e non posso usare l' idattributo per molti widget senza cadere nella unique id per pagetrappola. L'unico modo accettabile per accedere al widget è tramite form + widget_name.
MaxZoom,

5
@MaxZoom se hai così tanti moduli diversi sulla tua pagina con nomi di campo identici che hai problemi a trovare ID univoci, potresti voler riconsiderare un po 'il design della tua pagina, IMHO; ovviamente non conosco la tua situazione, ma questo ha un cattivo odore per me
Ken Bellows,

5
@kenbellows È un'idea di designer / business (non mia) mettere due moduli di ricerca su una pagina. Le migliori pratiche di esperienza utente possono cambiare nel tempo, ma l'HTML dovrebbe essere abbastanza flessibile (IMHO) per coprire qualsiasi scenario visibile.
MaxZoom,

Risposte:


529

Da w3: l'etichetta stessa può essere posizionata prima, dopo o attorno al controllo associato.

<label for="lastname">Last Name</label>
<input type="text" id="lastname" />

o

<input type="text" id="lastname" />
<label for="lastname">Last Name</label>

o

<label>
   <input type="text" name="lastname" />
   Last Name
</label>

Si noti che la terza tecnica non può essere utilizzata quando una tabella viene utilizzata per il layout, con l'etichetta in una cella e il campo del modulo associato in un'altra cella.

Uno dei due è valido. Mi piace usare il primo o il secondo esempio, poiché ti dà un maggiore controllo dello stile.


14
Come ho risposto, sono tutti validi, ma nella mia pratica mi accontento in genere del primo esempio fornito da superUntitled per caselle di testo, textareas e selezioni. Ma per i pulsanti di opzione e le caselle di controllo, di solito uso il terzo esempio, dove voglio l'input prima del testo di accompagnamento e non voglio lo stesso tipo di larghezza fissa e / o mobile che il resto delle etichette e dei campi sta usando. Quindi, in ogni singolo modulo, potresti trovarmi a utilizzare entrambi questi formati insieme.
Funka,

6
Mi chiedo se <label for="inputbox"><input id="inputbox" type="text" /></label>è un passaggio secondo i loro criteri.
Matt,

64
Peccato che non sia possibile nidificare un'etichetta all'interno di un tag di input. Sarebbe molto più semanticamente razionale, poiché l'etichetta è davvero una proprietà dell'input, se la vedi da un punto di vista astratto.
Alex

9
Il documento WCAG collegato include la seguente opzione "Il controllo è contenuto in un elemento etichetta che contiene il testo dell'etichetta". Non so se sia stato aggiunto negli anni da quando @Sorcy ha commentato, ma lo scenario di input-in-label è considerato valido ora.
Alex Weitzer,

6
Si è verificato un problema con l'input all'interno dell'etichetta, almeno in Chrome, quando si collega un gestore eventi click all'etichetta, il gestore viene attivato due volte quando si fa clic sull'etichetta. Puoi farlo con return false;alla fine del gestore, ma se possiedi altri gestori che devono essere eseguiti in seguito, e interrompere la propagazione non è un'opzione, questo diventa un problema.
wired_in

67

preferisco

<label>
  Firstname
  <input name="firstname" />
</label>

<label>
  Lastname
  <input name="lastname" />
</label>

al di sopra di

<label for="firstname">Firstname</label>
<input name="firstname" id="firstname" />

<label for="lastname">Lastname</label>
<input name="lastname" id="lastname" />

Principalmente perché rende l'HTML più leggibile. E in realtà penso che il mio primo esempio sia più semplice da modellare con i CSS, poiché i CSS funzionano molto bene con elementi nidificati.

Ma suppongo sia una questione di gusti.


Se hai bisogno di più opzioni di stile, aggiungi un tag span.

<label>
  <span>Firstname</span>
  <input name="firstname" />
</label>

<label>
  <span>Lastname</span>
  <input name="lastname" />
</label>

Secondo me, il codice sembra ancora migliore.


3
Includere l'input all'interno dell'etichetta è lo stesso che usare HTML per il layout.
Emil,

8
Mi piace questa soluzione anche per casi come questo: <label>Expires after <input name="exp" /> days</label>(l'etichetta è prima e dopo l'elemento di input)
Philipp

Penso che l'ultimo esempio sia - oltre agli attributi for e id - non molto diverso dall'avere l'etichetta vicino all'input ed entrambi racchiusi in un div, lio cosa no, vero !?
retrovertigo,

1
@retrovertigo - funzionalmente? No. Riduce solo il markup e riduce l'uso eccessivo semantico di termini. Sappiamo che l'input firstnamedovrebbe seguire l'etichetta per firstname, ma i browser hanno bisogno della dichiarazione. È tutta una questione di gusti e ciò che TU pensi sia il migliore (ed è più facile eseguire il debug) nel tuo codice. Preferisco usare il nidificato ora, anche se mi ci è voluto un po 'per abituarmi.
Xhynk,

3
@MPavlak: una rapida occhiata e ho trovato questa guida da w3.org. w3.org/WAI/tutorials/forms/labels . Ho quindi controllato w3.org/TR/WCAG20-TECHS/H44.html . In fondo (è oscuro) si dice che per rivendicare la conformità, è necessario superare i criteri di test e che afferma specificamente che è necessario utilizzare l'attributo for. In realtà, quando l'ho testato l'ultima volta in Apple Voiceover (desktop con 10% di sharescreen per desktop, 60% con screen reader per mobile) le etichette implicite non hanno funzionato, quindi questo è stato un altro fattore importante. Spero che aiuti!
James Westgate,

39

Se includi il tag di input nel tag label, non è necessario utilizzare l'attributo 'for'.

Detto questo, non mi piace includere il tag di input nelle mie etichette perché penso che siano entità separate, non contenenti.


8
Il for richiede di usare un id, il che rende la strutturazione gerarchica del layout molto difficile :-(
lethalman,

39

Differenza di comportamento: fare clic nello spazio tra etichetta e input

Se si fa clic sullo spazio tra l'etichetta e l'input, si attiva l'input solo se l'etichetta contiene l'input.

Questo ha senso poiché in questo caso lo spazio è solo un altro personaggio dell'etichetta.

<p>Inside:</p>

<label>
  <input type="checkbox" />
  |&lt;----- Label. Click between me and the checkbox.
</label>

<p>Outside:</p>

<input type="checkbox" id="check" />
<label for="check">|&lt;----- Label. Click between me and the checkbox.</label>

Essere in grado di fare clic tra etichetta e scatola significa che è:

  • più facile da cliccare
  • meno chiaro dove le cose iniziano e finiscono

Gli esempi della casella di controllo v3.3 Bootstrap usano l'input all'interno: http://getbootstrap.com/css/#forms Potrebbe essere saggio seguirli. Ma hanno cambiato idea in v4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios, quindi non so più cosa sia saggio:

Le caselle di controllo e le radio utilizzate sono create per supportare la convalida dei moduli basata su HTML e fornire etichette concise e accessibili. Come tale, i nostri <input>s <label>sono elementi di pari livello rispetto a <input>all'interno di un <label>. Questo è leggermente più dettagliato in quanto è necessario specificare id e affinchè gli attributi mettano in relazione <input>e <label>.

Domanda sulla UX che discute in dettaglio questo punto: /ux/23552/should-the-space-b Between - the - checkbox - and - label - be - clickable


Questa non è una differenza specifica. L'interruttore funziona per entrambi i casi in tutti i browser compatibili.
hexalys,

@hexalys Grazie per la segnalazione. Ho aggiornato la risposta. Vuoi dire che i browser conformi dovrebbero attivare o disattivare entrambi i casi? Se potessi collegarti al passaggio standard pertinente sarebbe fantastico.
Ciro Santilli 26 冠状 病 六四 事件 法轮功

1
Sì. Anche se non ho notato che il tuo esempio è fuorviante perché il tuo spazio non è in realtà uno spazio di testo . È una margindelle caselle di controllo. Il comportamento di Firefox sul tuo esempio è peculiare e sembra un bug. A labelconterrà gli spazi o il riempimento attorno al contenuto incorporato come selezionabili. Ma dato che il modello di contenuto di un'etichetta è in linea / Phrasing content, il margine di input non dovrebbe essere cliccabile, a meno che l'etichetta non sia stata creata display: blocknel qual caso l'interno dell'etichetta blockdiventa cliccabile in tutti i browser.
hexalys,

1
Si noti che il collegamento Bootstrap nella risposta va ai documenti per v3.3. I documenti per la versione 4.0 sembrano indicare che hanno cambiato idea: "Le caselle di controllo e le radio sono costruite per supportare la convalida dei moduli basata su HTML e fornire etichette concise e accessibili. Pertanto, i nostri <input> e <label> s sono elementi di pari livello rispetto a un <input> all'interno di un <label>. Questo è leggermente più dettagliato in quanto è necessario specificare id e per gli attributi di mettere in relazione <input> e <label> ".
Michael Krebs,

2
Questa differenza di comportamento è la più grande per me. Quando gli elementi sono fratelli, qualsiasi margine su uno dei due elementi riduce l'area cliccabile che attiverà l'elemento di input. L'annidamento dell'input all'interno dell'etichetta conserva la massima area selezionabile, offrendo la massima accessibilità anche agli utenti che lottano con movimenti precisi del mouse o del tocco. In Bootstrap 4, l'annidamento funziona ancora e visualizza lo stesso senza dover regolare o sovrascrivere alcun CSS Bootstrap.
Turgs,

17

Personalmente mi piace tenere l'etichetta all'esterno, come nel tuo secondo esempio. Ecco perché l'attributo FOR è lì. Il motivo è che spesso applicherò stili all'etichetta, come una larghezza, per ottenere un aspetto gradevole del modulo (abbreviazione di seguito):

<style>
label {
  width: 120px;
  margin-right: 10px;
}
</style>

<label for="myinput">My Text</label>
<input type="text" id="myinput" /><br />
<label for="myinput2">My Text2</label>
<input type="text" id="myinput2" />

Fa in modo che io possa evitare i tavoli e tutta quella roba indesiderata nelle mie forme.


3
Non dovresti lasciare la presentazione ai CSS, invece di usarli <br />per separare gli input?
Znarkus,

1
@Znarkus - sì, normalmente li avvolgo in OL / LI per gestire una formattazione del genere, questo è solo un breve esempio di stenografia.
Pappagalli,

1
@Parrots: non ha molto senso semanticamente, imo. E se devi avvolgerli, perché non avvolgerli semplicemente con l'etichetta?
Znarkus,

1
@Parrots Con questo ragionamento penso che tutto in una pagina dovrebbe andare dentro ul / li. E con <label> <span>My text</span> <input /> </label>te hai tutte le opzioni di stile di cui avresti (mai) bisogno.
Znarkus,

1
L'uso di "for" ti impone di utilizzare un ID, il che è negativo per i layout gerarchici.
lethalman,

15

Vedi http://www.w3.org/TR/html401/interact/forms.html#h-17.9 per le raccomandazioni W3.

Dicono che può essere fatto in entrambi i modi. Descrivono i due metodi come espliciti (usando "for" con l'id dell'elemento) e impliciti (incorporando l'elemento nell'etichetta):

Esplicito:

L'attributo for associa esplicitamente un'etichetta a un altro controllo: il valore dell'attributo for deve essere uguale al valore dell'attributo id dell'elemento di controllo associato.

Implicito:

Per associare implicitamente un'etichetta a un altro controllo, l'elemento di controllo deve trovarsi all'interno del contenuto dell'elemento LABEL. In questo caso, l'ETICHETTA può contenere solo un elemento di controllo.


Ho appena scoperto che l'implicito non funziona in IE ... .Qualche idea?
carinlynchin,

11

Entrambi sono corretti, ma l'inserimento dell'input all'interno dell'etichetta lo rende molto meno flessibile durante lo styling con CSS.

Innanzitutto, a <label>è limitato in quali elementi può contenere . Ad esempio, puoi solo inserire un testo <div>tra <input>e il testo dell'etichetta, se <input>non è all'interno di <label>.

In secondo luogo, mentre ci sono soluzioni alternative per rendere più semplice lo stile come avvolgere il testo dell'etichetta interna con un arco, alcuni stili verranno ereditati dagli elementi padre, il che può rendere lo stile più complicato.


molto meno flessibile? Puoi elaborare? come altri hanno già detto, puoi semplicemente avvolgere il testo dell'etichetta interna con un arco, a meno che non sia ciò che lo rende molto meno flessibile?
MPavlak,

7

Un 'gotcha' notevole impone che non si debba mai includere più di un elemento di input all'interno di un elemento <label> con un attributo esplicito "for", ad esempio:

<label for="child-input-1">
  <input type="radio" id="child-input-1"/>
  <span> Associate the following text with the selected radio button: </span>
  <input type="text" id="child-input-2"/>
</label>

Sebbene ciò possa essere allettante per le funzionalità del modulo in cui un valore di testo personalizzato è secondario rispetto a un pulsante di opzione o casella di controllo, la funzionalità di attivazione del clic dell'elemento etichetta attiverà immediatamente l'elemento il cui ID è esplicitamente definito nell'attributo 'for' , rendendo quasi impossibile per l'utente fare clic nel campo di testo contenuto per inserire un valore.

Personalmente, provo a evitare gli elementi dell'etichetta con i figli di input. Sembra semanticamente improprio che un elemento etichetta includa più dell'etichetta stessa. Se stai annidando gli input nelle etichette per ottenere una certa estetica, dovresti invece usare CSS.


4
Questo non è un "gotcha". Fa esplicitamente parte delle specifiche; l'etichetta può contenere al massimo 1 controllo. Stai anche mescolando gli stili impliciti ed espliciti qui - se metti il ​​controllo all'interno dell'etichetta, non hai bisogno for... e se vuoi usare for, avere il controllo all'interno dell'etichetta non ha molto senso .
cHao,

Vero, ma sembrerebbe che questa specifica non sia ben compresa. Abbiamo riscontrato questo problema con l'API dei moduli di Drupal 6, che ha generato markup che ha creato uno scenario non dissimile da quello sopra descritto. Aveva un mio collega e io ci grattavamo la testa per un minuto o due, quindi ho pensato di risolvere il problema qui per evitare potenziali confusioni in futuro.
Aaron,

non è necessario "for" nello scenario di input label->. un input per etichetta e ha il vantaggio di non dover conoscere il nome o l'id e puoi fare uno stile CSS per mantenere le cose incapsulate e avere lo stato attivo quando si fa clic su qualsiasi altro elemento simile all'interno. vedi zipstory.com/signup per un esempio di come fare questo.
Jason Sebring,

Grazie; questo ha risposto a un'altra domanda correlata che avevo, vale a dire se si tratta di avere potenzialmente più di un input all'interno di un'etichetta. (Contesto: diverse opzioni del pulsante di opzione, una per riga, ciascuna voce del pulsante di opzione con 1, 2, 3 o possibilmente più input di tipo testo, con l'intento di fare clic su una riga con il risultato di selezionare il pulsante di opzione, se non selezionato e che consente la modifica dell'input / input su quella riga.) Questo lascia aperta la porta ad avere più etichette per il testo non input nel modulo, ma ha risposto alla mia domanda se ciò che pensavo fosse OK. (Non lo era.)
Christos Hayward,

6

Come molte persone hanno detto, in entrambi i modi funzionano davvero, ma penso che solo il primo dovrebbe funzionare. Essendo semanticamente rigoroso, l'etichetta non "contiene" l'input. Secondo me, la relazione di contenimento (genitore / figlio) nella struttura di markup dovrebbe riflettere il contenimento nell'output visivo . cioè, un elemento che circonda un altro nel markup dovrebbe essere disegnato attorno a quello nel browser . In base a ciò, l'etichetta dovrebbe essere il fratello dell'input, non il genitore. Quindi l'opzione numero due è arbitraria e confusa. Chiunque abbia letto lo Zen di Python sarà probabilmente d'accordo (Flat è meglio di nidificato, Sparse è meglio di denso, Dovrebbe esserci uno - e preferibilmente solo un - modo evidente per farlo ...).

A causa di decisioni come quelle del W3C e dei principali fornitori di browser (che consentono "qualunque sia il modo in cui preferisci farlo", invece di "farlo nel modo giusto") è che il Web è così incasinato oggi e noi sviluppatori dobbiamo fare i conti con e così diverso codice legacy.


5

Di solito vado con le prime due opzioni. Ho visto uno scenario in cui è stata utilizzata la terza opzione, quando le scelte radio erano incorporate nelle etichette e nei CSS contenevano qualcosa di simile

label input {
    vertical-align: bottom;
}

al fine di garantire un corretto allineamento verticale delle radio.



2

Preferisco di gran lunga avvolgere gli elementi dentro di me <label>perché non devo generare gli ID.

Sono uno sviluppatore Javascript e React o Angular vengono utilizzati per generare componenti che possono essere riutilizzati da me o da altri. Sarebbe quindi facile duplicare un ID nella pagina, portando lì a comportamenti strani.


1

Una cosa da considerare è l'interazione della casella di controllo e degli ingressi radio con javascript.

Utilizzando la struttura sottostante:

<label>
  <input onclick="controlCheckbox()" type="checkbox" checked="checkboxState" />
  <span>Label text</span>
</label>

Quando l'utente fa clic sulla funzione controlCheckbox () "Etichetta testo" verrà attivata una volta.

Ma quando si fa clic sul tag di input, la funzione controlCheckbox () può essere attivata due volte in alcuni browser meno recenti. Questo perché sia ​​i tag di input che quelli di etichetta attivano l'evento onclick associato alla casella di controllo.

Quindi potresti avere alcuni bug nella tua casella di controllo Stato.

Ho riscontrato questo problema di recente su IE11. Non sono sicuro se i browser moderni abbiano problemi con questa struttura.


-1

Il vantaggio principale di collocare inputall'interno dilabel è la tipizzazione dell'efficienza per l'uomo e l'archiviazione dei byte per i computer.

@Znarkus ha detto nel suo commento all'OP,

Uno dei grandi pro di mettere <input />dentro l' interno <label>è che puoi omettere fore id: <label>My text <input /></label>nel tuo esempio. Molto più bello!

Nota: nel codice @Znarknus è stata inclusa un'altra efficienza non esplicitamente dichiarata nel commento. type="text"può anche essere omesso e inputvisualizzerà una casella di testo per impostazione predefinita.

Un confronto fianco a fianco di sequenze di tasti e byte [1].

31 sequenze di tasti, 31 byte

<label>My Text<input /></label>

58 battute, 58 byte

<label for="myinput">My Text</label><input id="myinput" />

Altrimenti, i frammenti sono visivamente uguali e offrono lo stesso livello di accessibilità dell'utente. Un utente può fare clic o toccare l'etichetta per posizionare il cursore nella casella di testo.

[1] File di testo (.txt) creati in Blocco note su Windows, byte dalle proprietà di Esplora file di Windows

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.