¿Debo poner elementos de entrada dentro de un elemento de etiqueta?


606

¿Hay una mejor práctica en relación con la anidación de labely inputelementos HTML?

forma clásica:

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

o

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

107
Una de las grandes ventajas de poner el <input />interior <label>es que puede omitir fory id: <label>My text <input /></label>en su ejemplo. Mucho mejor!
Znarkus

16
Si bien estoy de acuerdo en que inputno pertenece semánticamente dentro de un label, noté hoy que los desarrolladores de Bootstrap no están de acuerdo conmigo . Algunos elementos, como las casillas de verificación en línea, tienen un estilo diferente dependiendo de si inputestá dentro o fuera.
Blazemonger

66
Por cierto, fue una idea realmente mala crear, <label for="id">ya que tengo varios formularios en la página y no puedo usar el idatributo para muchos widgets sin caer en la unique id per pagetrampa. La única forma aceptable de acceder al widget es mediante form + widget_name.
MaxZoom

55
@MaxZoom si tiene tantos formularios diferentes en su página con nombres de campo idénticos que tiene problemas para encontrar identificaciones únicas, es posible que desee reconsiderar un poco el diseño de su página, en mi humilde opinión; obviamente no conozco tu situación, pero eso me huele mal
Ken Bellows

55
@kenbellows Es una idea del diseñador / negocio (no es mi) poner dos formularios de búsqueda en una página. Las mejores prácticas de experiencia de usuario pueden cambiar con el tiempo, pero el HTML debe ser lo suficientemente flexible (IMHO) para cubrir cualquier escenario visible.
MaxZoom

Respuestas:


529

Desde w3: la etiqueta puede colocarse antes, después o alrededor del control asociado.

<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>

Tenga en cuenta que la tercera técnica no se puede usar cuando se usa una tabla para el diseño, con la etiqueta en una celda y su campo de formulario asociado en otra celda.

Cualquiera de los dos es válido. Me gusta usar el primer o segundo ejemplo, ya que te da más control de estilo.


14
Como respondí, todos son válidos, pero en mi propia práctica generalmente me conformo con el primer ejemplo dado aquí por superUntitled para cuadros de texto, áreas de texto y selecciones. Pero para los botones de opción y las casillas de verificación, generalmente utilizo el tercer ejemplo, donde quiero la entrada antes del texto que lo acompaña y no quiero el mismo tipo de ancho fijo y / o flotante que el resto de las etiquetas y los campos están usando. Entonces, en cualquier formulario dado, puede encontrarme usando ambos formatos juntos.
Funka

66
Me pregunto si <label for="inputbox"><input id="inputbox" type="text" /></label>es un pase de acuerdo a sus criterios.
Matt

64
Lástima que no pueda anidar una etiqueta dentro de una etiqueta de entrada. Sería mucho más semánticamente racional, ya que la etiqueta realmente es una propiedad de la entrada, si la ve desde un punto de vista abstracto.
Alex

99
El documento WCAG vinculado incluye la siguiente opción "El control está contenido dentro de un elemento de etiqueta que contiene el texto de la etiqueta". No sé si eso se agregó en los años transcurridos desde que @Sorcy comentó, pero el escenario de entrada en la etiqueta se considera válido ahora.
Alex Weitzer

66
Hay un problema con la entrada dentro de la etiqueta, al menos en Chrome, cuando adjunta un controlador de eventos de clic a la etiqueta, el controlador se dispara dos veces cuando se hace clic en la etiqueta. Puede superar esto return false;al final del controlador, pero si posiblemente tiene otros controladores que necesitan ejecutarse después, y detener la propagación no es una opción, esto se convierte en un problema.
wired_in

67

yo prefiero

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

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

terminado

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

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

Principalmente porque hace que el HTML sea más legible. Y realmente creo que mi primer ejemplo es más fácil de diseñar con CSS, ya que CSS funciona muy bien con elementos anidados.

Pero es cuestión de gustos, supongo.


Si necesita más opciones de estilo, agregue una etiqueta span.

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

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

El código todavía se ve mejor en mi opinión.


3
Incluir la entrada dentro de la etiqueta es lo mismo que usar HTML para el diseño.
Emil

8
Me gusta esta solución también para casos como este: <label>Expires after <input name="exp" /> days</label>(la etiqueta es antes y después del elemento de entrada)
Philipp

Creo que el último ejemplo es, además de los atributos for y id, en realidad no es diferente de tener la etiqueta al lado de la entrada y ambas envueltas en una div, li¿o no?
retrovertigo

1
@retrovertigo - ¿funcionalmente? No. Simplemente reduce el marcado y reduce el uso excesivo semántico de los términos. Sabemos que la entrada firstnamedebe seguir la etiqueta firstname, pero los navegadores necesitan la declaración. Todo es cuestión de gustos y lo que USTED cree que se ve mejor (y es más fácil de depurar) en su código. Prefiero usar anidado ahora, aunque me tomó un tiempo acostumbrarme.
Xhynk

3
@MPavlak: un vistazo rápido y encontré esta guía de w3.org. w3.org/WAI/tutorials/forms/labels . Luego revisé w3.org/TR/WCAG20-TECHS/H44.html . En la parte inferior (es oscuro) dice que para reclamar conformidad, debe pasar los criterios de prueba, y eso establece específicamente que debe usar el atributo for. En realidad, cuando probé esto por última vez en Apple Voiceover (10% de cuota de mercado de lectores de pantalla de escritorio, 60% de cuota de mercado de lectores de pantalla móviles), las etiquetas implícitas no funcionaron, por lo que ese fue otro factor importante. ¡Espero que ayude!
James Westgate

39

Si incluye la etiqueta de entrada en la etiqueta de la etiqueta, no necesita usar el atributo 'for'.

Dicho esto, no me gusta incluir la etiqueta de entrada en mis etiquetas porque creo que son entidades separadas, que no contienen.


8
Sin embargo, for requiere que use una identificación, lo que hace que estructurar el diseño jerárquicamente sea muy difícil :-(
lethalman

39

Diferencia de comportamiento: hacer clic en el espacio entre la etiqueta y la entrada

Si hace clic en el espacio entre la etiqueta y la entrada, se activa la entrada solo si la etiqueta contiene la entrada.

Esto tiene sentido ya que en este caso el espacio es solo otro carácter de la etiqueta.

<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>

Poder hacer clic entre la etiqueta y el cuadro significa que es:

  • más fácil de hacer clic
  • menos claro dónde comienzan y terminan las cosas

Los ejemplos de la casilla de verificación Bootstrap v3.3 usan la entrada que se encuentra en el interior: http://getbootstrap.com/css/#forms Puede ser prudente seguirlos. Pero cambiaron de opinión en v4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios, así que ya no sé lo que es sabio:

Las casillas de verificación y el uso de radios están diseñados para admitir la validación de formularios basada en HTML y proporcionar etiquetas concisas y accesibles. Como tal, nuestros <input>s y <label>s son elementos de hermanos en lugar de un <input>plazo de un <label>. Esto es un poco más detallado ya que debe especificar id y para que los atributos relacionen el <input>y <label>.

Pregunta de UX que analiza este punto en detalle: /ux/23552/should-the-space-between-the-checkbox-and-label-be-clickable


Esta no es una diferencia de especificaciones. La palanca funciona para ambos casos en todos los navegadores compatibles.
hexalys

@hexalys Gracias por el informe. He actualizado la respuesta. ¿Quiere decir que los navegadores compatibles deberían alternar o no en ambos casos? Si pudieras enlazar con el pasaje estándar relevante, sería increíble.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
Si. Aunque no noté que su ejemplo es engañoso porque su espacio no es realmente un espacio de texto . Es una marginde la casilla de verificación. El comportamiento de Firefox en su ejemplo es peculiar y parece un error. A labelcontendrá los espacios o el relleno alrededor del contenido en línea como cliqueable. Pero dado que el modelo de contenido de una etiqueta está en línea / redactando contenido, el margen de entrada no debe ser cliqueable, a menos que su etiqueta esté hecha, display: blocken cuyo caso el interior de la etiqueta blockse puede hacer clic en todos los navegadores.
hexalys

1
Tenga en cuenta que el enlace Bootstrap en la respuesta va a los documentos para v3.3. Los documentos para v4.0 parecen indicar que han cambiado de opinión: "Las casillas de verificación y el uso de radios están diseñados para admitir la validación de formularios basada en HTML y proporcionar etiquetas concisas y accesibles. Como tal, nuestros <input> sy <label> s son elementos hermanos en lugar de un <input> dentro de un <label>. Esto es un poco más detallado ya que debe especificar id y para que los atributos relacionen el <input> y <label> ".
Michael Krebs

2
Esta diferencia de comportamiento es la más importante para mí. Cuando los elementos son hermanos, cualquier margen en cualquiera de los elementos reduce el área de superficie en la que se puede hacer clic que activará el elemento de entrada. Anidar la entrada dentro de la etiqueta conserva el área máxima en la que se puede hacer clic, lo que brinda la máxima accesibilidad incluso para usuarios que luchan con movimientos precisos del mouse o táctiles. En Bootstrap 4, el anidamiento aún funciona y todavía muestra lo mismo sin necesidad de ajustar o anular ningún CSS de Bootstrap.
Turgs

17

Personalmente, me gusta mantener la etiqueta afuera, como en tu segundo ejemplo. Es por eso que el atributo FOR está ahí. La razón es que a menudo aplicaré estilos a la etiqueta, como un ancho, para que el formulario se vea bien (abreviatura a continuación):

<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" />

Lo hace para poder evitar las tablas y toda esa basura en mis formularios.


3
¿No deberías dejar la presentación en CSS, en lugar de usar <br />para separar las entradas?
Znarkus

1
@ Znarkus: sí, normalmente los envuelvo en OL / LI para tratar con un formato como ese, este fue solo un ejemplo breve y abreviado.
Loros

1
@Parrots: Eso no tiene mucho sentido semánticamente, en mi opinión. Y si necesita envolverlos, ¿por qué no simplemente envolverlos con la etiqueta?
Znarkus

1
@Parrots Con ese razonamiento, creo que todo en una página debe ir dentro de ul / li. Y con <label> <span>My text</span> <input /> </label>usted tiene todas las opciones de estilo que necesitaría (alguna vez).
Znarkus

1
El uso de "for" obliga a usar una identificación, lo cual es malo para los diseños jerárquicos.
lethalman

15

Consulte http://www.w3.org/TR/html401/interact/forms.html#h-17.9 para ver las recomendaciones de W3.

Dicen que se puede hacer de cualquier manera. Describen los dos métodos como explícito (usando "for" con la identificación del elemento) e implícito (incrustando el elemento en la etiqueta):

Explícito:

El atributo for asocia explícitamente una etiqueta con otro control: el valor del atributo for debe ser el mismo que el valor del atributo id del elemento de control asociado.

Implícito:

Para asociar una etiqueta con otro control implícitamente, el elemento de control debe estar dentro del contenido del elemento LABEL. En este caso, la ETIQUETA solo puede contener un elemento de control.


Acabo de descubrir que lo implícito no funciona en IE ... ¿alguna idea?
carinlynchin

11

Ambos son correctos, pero poner la entrada dentro de la etiqueta hace que sea mucho menos flexible al diseñar con CSS.

Primero, a <label>está restringido en qué elementos puede contener . Por ejemplo, solo puede poner un <div>entre el <input>texto de la etiqueta y, si <input>no está dentro del <label>.

En segundo lugar, si bien existen soluciones alternativas para facilitar el estilo, como ajustar el texto de la etiqueta interna con un espacio, algunos estilos se heredarán de los elementos principales, lo que puede hacer que el estilo sea más complicado.


mucho menos flexible? ¿puedes elaborar? como otros han mencionado, simplemente puede envolver el texto de la etiqueta interna con un espacio, a menos que eso sea lo que lo hace mucho menos flexible.
MPavlak

7

Un 'gotcha' notable indica que nunca debe incluir más de un elemento de entrada dentro de un elemento <label> con un atributo explícito "for", por ejemplo:

<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>

Si bien esto puede ser tentador para las características de formulario en las que un valor de texto personalizado es secundario a un botón de opción o casilla de verificación, la funcionalidad de enfoque de clic del elemento de etiqueta arrojará inmediatamente el foco al elemento cuya identificación se define explícitamente en su atributo 'for' , lo que hace casi imposible que el usuario haga clic en el campo de texto contenido para ingresar un valor.

Personalmente, trato de evitar elementos de etiqueta con elementos secundarios de entrada. Parece semánticamente inapropiado que un elemento de etiqueta abarque más que la etiqueta misma. Si está anidando entradas en etiquetas para lograr una cierta estética, debería usar CSS en su lugar.


44
Esto no es un "gotcha". Es explícitamente parte de la especificación; la etiqueta puede contener hasta 1 control en ella. También está mezclando los estilos implícito y explícito aquí: si coloca el control dentro de la etiqueta, no necesita for... y si desea usar for, entonces tener el control dentro de la etiqueta no tiene mucho sentido .
cHao

Es cierto, pero parece que esta especificación no se entiende bien. Nos encontramos con este problema con la API de formularios de Drupal 6, que generó un marcado que creó un escenario similar al descrito anteriormente. Tuvo a mi colega y a mí rascándonos la cabeza durante un minuto o dos, así que pensé en expresar el problema aquí para evitar una posible confusión en el futuro.
Aaron

no es necesario "for" en etiqueta-> escenario de entrada. una entrada por etiqueta y tiene la ventaja de no tener que saber el nombre o la identificación, y puede hacer un buen estilo css para mantener las cosas encapsuladas y hacer que el foco ocurra cuando se hace clic en cualquier otro elemento. visite zipstory.com/signup para ver una forma limpia de hacerlo.
Jason Sebring

Gracias; Esto respondió otra pregunta relacionada que tenía, a saber, si va a tener potencialmente más de una entrada dentro de una etiqueta. (Contexto: varias opciones de botón de radio, una por línea, cada entrada de botón de radio tiene 1, 2, 3 o posiblemente más entradas de texto de tipo, con la intención de hacer clic en una línea que tenga el resultado de seleccionar el botón de radio de esa línea, si no seleccionado, y permitiendo la edición de la entrada / entradas en esa línea.) Esto deja la puerta abierta a tener múltiples etiquetas para texto sin entrada en el formulario, pero respondió a mi pregunta sobre si lo que pensaba que estaba bien. (No lo fue)
Christos Hayward

6

Como la mayoría de la gente ha dicho, ambas formas funcionan, pero creo que solo la primera debería. Siendo semánticamente estricto, la etiqueta no "contiene" la entrada. En mi opinión, la relación de contención (padre / hijo) en la estructura de marcado debe reflejar la contención en la salida visual . es decir, un elemento que rodea a otro en el marcado debe dibujarse alrededor de ese en el navegador . De acuerdo con esto, la etiqueta debe ser el hermano de la entrada, no su padre. Entonces la opción número dos es arbitraria y confusa. Todos los que hayan leído el Zen de Python probablemente estarán de acuerdo (Flat es mejor que anidado, Sparse es mejor que denso, debería haber una, y preferiblemente solo una, forma obvia de hacerlo ...).

Debido a decisiones como esa del W3C y de los principales proveedores de navegadores (permitiendo "la forma que prefieras", en lugar de "hacerlo de la manera correcta") es que la web está tan desordenada hoy y los desarrolladores tenemos que lidiar con problemas y un código heredado tan diverso.


5

Normalmente voy con las dos primeras opciones. He visto un escenario en el que se usaba la tercera opción, cuando las opciones de radio estaban incrustadas en etiquetas y el CSS contenía algo como

label input {
    vertical-align: bottom;
}

para asegurar una alineación vertical adecuada para las radios.



2

Prefiero encapsular elementos dentro de mi <label>porque no tengo que generar los identificadores.

Soy un desarrollador de Javascript, y React o Angular se utilizan para generar componentes que pueden ser reutilizados por mí u otros. Entonces sería fácil duplicar una identificación en la página, lo que llevaría a comportamientos extraños.


1

Una cosa que debe considerar es la interacción de las casillas de verificación y las entradas de radio con javascript.

Usando la siguiente estructura:

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

Cuando el usuario hace clic en "Etiqueta de texto", la función controlCheckbox () se activará una vez.

Pero cuando se hace clic en la etiqueta de entrada, la función controlCheckbox () puede activarse dos veces en algunos navegadores más antiguos. Esto se debe a que las etiquetas de entrada y etiqueta activan el evento onclick adjunto a la casilla de verificación.

Entonces puede tener algunos errores en su casilla de verificación Estado.

Me he encontrado con este problema últimamente en IE11. No estoy seguro si los navegadores modernos tienen problemas con esta estructura.


-1

La principal ventaja de colocar inputdentro labeles la eficiencia de escritura para humanos y el almacenamiento de bytes para computadoras.

@ Znarkus dijo en su comentario al OP:

Una de las grandes ventajas de poner el <input />interior <label>es que puede omitir fory id: <label>My text <input /></label>en su ejemplo. Mucho mejor!

Nota: En el código @Znarknus, se incluyó otra eficiencia que no se indicó explícitamente en el comentario. type="text"también se puede omitir y inputmostrará un cuadro de texto de forma predeterminada.

Una comparación lado a lado de las pulsaciones de teclas y bytes [1].

31 pulsaciones de teclas, 31 bytes

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

58 pulsaciones de teclas, 58 bytes

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

De lo contrario, los fragmentos son visualmente iguales y ofrecen el mismo nivel de accesibilidad del usuario. Un usuario puede hacer clic o tocar la etiqueta para colocar el cursor en el cuadro de texto.

[1] Archivos de texto (.txt) creados en el Bloc de notas en Windows, bytes de las propiedades del Explorador de archivos de Windows

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.