Hoy · Hoja de ruta
- 1. Aprende: Cómo se agrupan opciones excluyentes y múltiples, y cuáles son los fallos que se repiten en todos los formularios mal hechos.
- 2. Haz: Termina tu formulario y audita uno defectuoso.
- 3. Comprueba: Recorre tu formulario usando solo la tecla
Tab.
Antes de empezar · 5 minutos, sin apuntes
- ¿Qué ventajas aporta
type="email"frente atype="text"? - ¿Cuándo usarías
textareay cuándoselect? - Predice qué ocurre al enviar vacío un campo con
required.
Botones de opción · cuando solo se puede elegir una
<fieldset>
<legend>Modalidad de envío</legend>
<label>
<input type="radio" name="envio" value="estandar">
Estándar
</label>
<label>
<input type="radio" name="envio" value="urgente">
Urgente
</label>
</fieldset>
La exclusión mutua entre dos botones de opción la produce compartir exactamente el mismo name, no el fieldset. Si puedes marcar los dos a la vez, tienen name distinto.
Fíjate también en otra forma de asociar la etiqueta: aquí el input está dentro del label, y entonces no hace falta for. Las dos formas son válidas.
Casillas · cuando se pueden elegir varias
<fieldset>
<legend>¿Qué tecnologías conoces?</legend>
<label><input type="checkbox" name="tec" value="html"> HTML</label>
<label><input type="checkbox" name="tec" value="css"> CSS</label>
<label><input type="checkbox" name="tec" value="js"> JavaScript</label>
</fieldset>
Una casilla independiente y obligatoria se declara así:
<label>
<input type="checkbox" name="condiciones" required>
Acepto las condiciones
</label>
fieldset y legend
Agrupan controles que forman una misma pregunta y le ponen nombre al grupo. En un formulario de tres campos sobran; en uno de quince son lo que lo hace navegable, porque cada campo se anuncia precedido del nombre de su grupo.
En los botones de opción no resultan prescindibles en la práctica: el legend es lo único que indica sobre qué se está eligiendo. No todo tiene que ser un div.
Autocompletado
<input type="text" name="nombre" autocomplete="name">
<input type="email" name="email" autocomplete="email">
Los navegadores usan esta información para rellenar por ti. Cuesta un atributo y ahorra bastante escritura a quien usa tu web.
Tarea 12 · Fase C · El formulario completo
Termina tu formulario con:
- Dos botones de opción que compartan
name, dentro de unfieldsetcon sulegend. - Un grupo de casillas para selección múltiple.
- Una casilla obligatoria de aceptación de condiciones.
- Dos
fieldsetque separen los datos personales de los de la consulta.
Estoy atascado · los radio no funcionan como espero
Si puedes marcar los dos a la vez, es que tienen name distinto. Lo que agrupa unos botones de opción es compartir exactamente el mismo name, y no el fieldset. Lo que sí debe ser distinto en cada uno es el value, que es el dato que se envía, y el id si los asocias con for.
Los seis fallos de siempre
Antes de mirar código, una prueba que dura treinta segundos y sirve para cualquier web: suelta el ratón. Recorre el formulario con Tab, cambia de opción con las flechas, envía con Enter. Si no sabes dónde está el foco, o hay algo que no puedes alcanzar, ese formulario está roto para todo el que no use un ratón.
| Fallo | Consecuencia |
|---|---|
Campos sin label asociado |
Se anuncian como «campo de texto», sin nombre |
placeholder usado como etiqueta |
La indicación desaparece al escribir |
type="text" para correos, números o fechas |
Sin validación ni teclado adaptado |
Campos sin name |
El dato no llega al servidor aunque se rellene |
<div onclick> como botón de enviar |
No se alcanza con Tab ni se activa con Enter |
<br> para separar los campos |
El formulario no tiene estructura, solo saltos de línea |
Tarea 13 · El formulario defectuoso
<form action="/enviar">
Nombre: <input type="text" placeholder="Escribe tu nombre">
<br>
Correo: <input type="text" placeholder="Escribe tu correo">
<br>
Edad: <input type="text">
<br>
<div class="boton-enviar" onclick="enviar()">Enviar formulario</div>
</form>
Paso 1 · Te enseño uno
- Fallo
- El texto «Nombre:» está suelto delante del campo, no es un
<label>. - ¿Por qué importa, si se lee igual?
- Se lee igual para quien ve la pantalla. Para un lector de pantalla no existe ninguna relación entre ese texto y ese campo: anunciará «campo de texto» y habrá que adivinar cuál es.
- Corrección
<label for="nombre">Nombre</label>y<input type="text" id="nombre" name="nombre">.
Paso 2 · Ahora tú
- Enumera los seis fallos, en el mismo formato: qué está mal, a quién perjudica y cuál es la corrección.
- Reescribe el formulario entero corrigiéndolos todos.
- Pásale la prueba del teclado a tu versión.
Ver los seis fallos
1 · Ningún campo tiene <label> asociado: los textos están sueltos delante.
2 · Ningún campo tiene name, así que ningún dato llegaría al servidor.
3 · El correo usa type="text" en lugar de type="email".
4 · La edad usa type="text" en lugar de type="number" con min y max.
5 · El botón es un <div onclick>: no se alcanza con Tab ni se activa con teclado. Debe ser <button type="submit">.
6 · Los campos se separan con <br>, que no aporta estructura. Cada campo con su etiqueta debería ir en su propio bloque.
Checkpoint · fin de la sesión 15 y de la semana 5
- Tu formulario se recorre entero con
Tab, en un orden que tiene sentido. - Todos los campos tienen
labelasociado,idyname. - Cada campo usa el
typeque le corresponde. - Los botones de opción comparten
namey están dentro de unfieldsetconlegend. - El botón de envío es un
<button>.
Antes de cerrar · 2 minutos, sin mirar
- ¿Qué hace que dos botones de opción sean excluyentes?
- Un campo rellenado no llega al servidor. ¿Qué atributo falta?
- ¿En qué consiste la prueba del teclado y qué detecta?
Ver respuestas
1 · Compartir el mismo atributo name.
2 · El atributo name.
3 · Recorrer el formulario sin ratón, solo con Tab, flechas y Enter. Detecta elementos inalcanzables, foco invisible y falsos botones.
Microprueba semanal 5 · 5–10 minutos
Individual, sin IA y sin apuntes.
- Escribe un campo de correo con
label,id,namey validación nativa. - Explica qué hace que tres radios sean mutuamente excluyentes.
- Detecta dos fallos:
<label>Edad</label><input type="text" required>.