Formularios

Crea formularios bien organizados y etiquetados para que sean accesibles.

Etiquetas

Identifica los controles de formulario con su etiqueta correspondiente.

Etiqueta visible

Utiliza el elemento label para asociar la etiqueta con el control del formulario.

Ejemplo
HTML
<label for="name">Nombre</label>
<input type="text" id="name">

La etiqueta y el control del formulario se asocian usando los atributos for y id con el mismo valor.

Etiqueta oculta

Existen situaciones donde la función del control del formulario es visualmente explícita, sin necesidad de añadir una etiqueta. En ese caso podemos ocultar el elemento label o no incluirlo, pero debemos ofrecer una alternativa para las tecnologías asistivas.

Método 1: ocultar el elemento label

En el siguiente ejemplo, la función del formulario se intuye claramente con el texto del botón y, por tanto, podemos ocultar visualmente la etiqueta.

Ejemplo
HTML
<label for="search" class="sr-only">Buscar: </label>
<input type="text" id="search">
<button type="submit">Buscar</button>

Método 2: usar aria-label

Incluimos el atributo aria-label en el control del formulario y no utilizamos el elemento label.

Ejemplo
HTML
<input type="text" aria-label="Buscar">
<button type="submit">Buscar</button>

Botones

Si usamos el elemento button la etiqueta es el texto del botón.

HTML
<button type="submit">Enviar</button>

Y si usamos el elemento input la etiqueta es el texto del atributo value.

HTML
<input type="submit" value="Enviar">

Agrupar controles

Agrupar los controles relacionados facilita la comprensión y la interacción con el formulario.

Agrupar controles con el elemento fieldset

El elemento fieldset crea un contenedor para agrupar campos relacionados. Lo acompaña el elemento legend que identifica o describe al grupo.

Ejemplo
Datos de envío
HTML
<fieldset>
    <legend>Datos de envío</legend>
    <label for="name">Nombre</label>
    <input type="text" id="name">
    <label for="address">Dirección</label>
    <input type="text" id="address">
    <label for="city">Ciudad</label>
    <input type="text" id="city">
</fieldset>

Nota: Los controles de tipo radio y checkbox deberían agruparse siempre para ser tratados semánticamente como un único grupo.

Agrupar controles con WAI-ARIA

Una alternativa a fieldset y legend para agrupar controles relacionados es utilizar WAI-ARIA. Para ello agrupamos los controles con role=group y etiquetamos el grupo usando aria-labelledby con un id.

Ejemplo

Datos de envío

HTML
<div role="group" aria-labelledby="shipping-info">
    <h3 id="shipping-info">Datos de envío</h3>
    <label for="name">Nombre</label>
    <input type="text" id="name">
    <label for="address">Dirección</label>
    <input type="text" id="address">
    <label for="city">Ciudad</label>
    <input type="text" id="city">
</div>

Instrucciones

Proporciona instrucciones que ayuden a los usuarios a rellenar los formularios.

Instrucciones generales

Son instrucciones que afectan a todo el formulario. Pueden indicar qué entradas son obligatorias, el formato de datos, o cualquier otra información adicional.

El texto de las instrucciones debe incluirse antes de la etiqueta <form> debido a que algunos lectores de pantalla no leen los textos que no formen parte de elementos de formulario, cuando están dentro de <form>.

Instrucciones en línea

Son instrucciones relevantes que se incluyen junto al control del formulario.

Método 1: instrucciones dentro de label

La forma más simple de proporcionar instrucciones en línea es incluirlas dentro de la etiqueta label.

Ejemplo
HTML
<label for="email">Email (obligatorio)</label>
<input type="email" id="email">

Método 2: instrucciones usando WAI-ARIA

Se asocian las instrucciones con el control de formulario usando el atributo aria-labelledby.

Ejemplo
(obligatorio)
HTML
<label for="email">Email</label>
<input type="email" id="email" aria-labelledby="emailLabel">
<span id="emailLabel">(obligatorio)</span>

Método 3: instrucciones usando placeholder

El atributo placeholder nos permite incluir un texto dentro del campo de formulario que desaparece al empezar a escribir o, en algunos navegadores, al enfocar el campo.

Ejemplo
HTML
<label for="email">Email</label>
<input type="email" id="email" placeholder="usuario@empresa.com">

Este atributo es muy práctico pero presenta algunos problemas de accesibilidad:

  • Los lectores de pantalla no tratan placeholder como una etiqueta.
  • Al desaparecer la información puede que el usuario no recuerde las instrucciones proporcionadas.
  • Los navegadores suelen usar un tono más claro para el texto que no suele cumplir los requisitos mínimos de contraste, aunque esto se puede solucionar cambiando el color con CSS.

Nota: El atributo placeholder no debería sustituir a la etiqueta del control de formulario. Para evitar información redundante se puede ocultar la etiqueta visualmente.

Validación

Antes de enviar los datos de un formulario debemos validarlos y, si existe algún error, notificárselo al usuario.

Validar campos obligatorios

Los campos obligatorios deben identificarse claramente mediante etiquetas.

A nivel de código, podemos indicar que el campo es obligatorio añadiendo el atributo required. Si el campo queda vacío, al pulsar el botón de envío el navegador presentará un mensaje de aviso indicando que debe completarse.

Ejemplo
HTML
<label for="name">Nombre (obligatorio)</label>
<input type="text" id="name" required>
<button type="submit">Enviar</button>

Nota: Existe un atributo WAI-ARIA para indicar que un control es obligatorio: aria-required. En teoría no es necesario si ya existe el atributo required.

Validar tipos de datos

HTML proporciona atributos para los tipos de datos más comunes de un formulario (email, fecha, url, números etc.). Estos atributos permiten validar el formato de los datos insertados y, en algunos casos, presentan controles específicos.

Ejemplo
HTML
<label for="email">Email</label>
<input type="email" id="email">

<label for="date">Fecha</label>
<input type="date" id="date">

<label for="num">Número</label>
<input type="number" id="num">

Algunos tipos de datos pueden incluir parámetros adicionales como valores mínimo y máximo, longitud máxima de caracteres o el rango de aumento o disminución de un valor.

Validar patrones de datos

El atributo de HTML pattern permite validar los datos de un campo de entrada usando expresiones regulares.

Ejemplo
HTML
<label for="contrs">Contraseña<br>
<span class="small">Debe contener al menos un número o un caracter
especial y mínimo 8 caracteres.</span>
</label>
<input type="text" id="contrs"
pattern="(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n]).*$" required>
<button type="submit">Enviar</button>>

En el ejemplo anterior, si la contraseña no cumple los requisitos, el navegador muestra un mensaje indicando que el formato utilizado debe coincidir con el solicitado.

Validación del lado del servidor

Además de la validación en el cliente, también debe realizarse la validación en el servidor. Si el navegador no soporta alguna técnica utilizada o si los datos se modifican antes de enviarlos es fácil que se produzcan errores.

La validación en el servidor se trata además de una medida de seguridad necesaria.

Notificaciones

Una vez enviados los datos del formulario, hay que informar al usuario de forma clara de si todo ha ido bien o de si se ha producido algún error. Para ello podemos usar los siguientes elementos:

  • El título de página: es lo primero que suele leer un lector de pantalla, así el usuario se percata del error de forma inmediata.
  • El encabezado principal: suele ser el elemento más visible de la página.
  • Lista de errores: debe colocarse al principio de la página, antes del formulario y conviene enlazar cada elemento de la lista con el control correspondiente para su fácil localización.

Criterios de conformidad WCAG 2.1