Formularios

La mayoría de los sitios y las aplicaciones incluyen un formulario web. Los sitios de bromas, como DoWebsitesNeedToLookExactamenteElMismoEnTodosNavegador.com, pueden no tener un formulario, pero incluso MachineLearningWorkshop.com (MLW), que se originó como una broma del Día de los Inocentes, tienen un formulario, aunque es falso. El principal "llamado a la acción" de MLW es un formulario de registro para que las máquinas se inscriban en un taller. Este formulario se encuentra contenido en un elemento <form>.

El elemento HTML <form> identifica un punto de referencia de documento que contiene controles interactivos para enviar información. Anidado en un <form>, encontrarás todos los controles de formulario interactivos (y no interactivos) que lo componen.

El HTML es potente. En esta sección, se enfoca en la potencia de HTML y se explica lo que puede hacer sin agregar JavaScript. El uso de datos de formulario del cliente para actualizar la IU de alguna manera suele implicar CSS o JavaScript, que no se analizan aquí. Hay un curso completo de Aprende Formularios. No duplicaremos esa sección aquí, pero presentaremos varios controles de formulario y los atributos HTML que los potencian.

Con los formularios, puedes permitir que los usuarios interactúen con tu sitio web o aplicación, validen la información ingresada y envíen los datos a un servidor. Los atributos HTML pueden permitir que el usuario seleccione controles de formulario o ingrese un valor. Los atributos HTML pueden definir criterios específicos con los que el valor debe coincidir para ser válido. Cuando el usuario intenta enviar el formulario, todos los valores de control del formulario pasan por la validación de restricciones del cliente y pueden impedir el envío hasta que los datos coincidan con los criterios requeridos, todo sin JavaScript. También puedes desactivar esta función: configurar el atributo novalidate en <form> o, con mayor frecuencia, formnovalidate en un botón, guardar los datos del formulario para completarlos más adelante evita la validación.

Cómo enviar formularios

Los formularios se envían cuando el usuario activa un botón de envío anidado en él. Cuando se usa <input> para botones, el "valor" es la etiqueta del botón y se muestra en él. Cuando usas <button>, la etiqueta es el texto entre las etiquetas de apertura y cierre de <button>. Un botón de envío se puede escribir de dos maneras:

<input type="submit" value="Submit Form">
<button type="submit">Submit Form</button>

Para un formulario muy simple, necesitas un elemento <form>, con algunas entradas de formulario y un botón de envío. Sin embargo, enviar un formulario es mucho más que eso.

Los atributos del elemento <form> establecen el método HTTP mediante el cual se envía el formulario y la URL que procesa el envío del formulario. Sí, los formularios se pueden enviar, procesar y cargar una página nueva sin ningún JavaScript. El elemento <form> es así de potente.

Los valores de los atributos action y method del elemento <form> definen la URL que procesa los datos del formulario y el método HTTP que se usa para enviar los datos, respectivamente. De forma predeterminada, los datos del formulario se envían a la página actual. De lo contrario, configura el atributo action con la URL a la que se deben enviar los datos.

Los datos enviados se componen de pares nombre/valor de los diversos controles de formularios del formulario. De forma predeterminada, se incluyen todos los controles de formulario anidados que tienen un name. Sin embargo, con el atributo form, es posible incluir controles de formularios fuera de <form> y omitir los controles de formularios anidados dentro de <form>. Compatible con controles de formulario y <fieldset>, el atributo form toma como valor el id del formulario con el que está asociado el control, no necesariamente el formulario en el que está anidado. Esto significa que los controles de formulario no necesitan anidarse físicamente en un <form>.

El atributo method define el protocolo HTTP de la solicitud: generalmente, GET o POST. Con GET, los datos del formulario se envían como una cadena de parámetros de pares name=value, que se agrega a la URL de action.

Con POST, los datos se adjuntan al cuerpo de la solicitud HTTP. Cuando envíes datos seguros, como contraseñas y información de tarjetas de crédito, usa siempre POST.

También existe un método DIALOG. Si un <form method="dialog"> está dentro de una <dialog>, el envío del formulario cerrará el diálogo; hay un evento de envío aunque los datos no se borren ni se envíen. Una vez más, sin JavaScript. Esto se analiza en la sección de diálogo. Ten en cuenta que, como esto no envía el formulario, es probable que desees incluir formmethod="dialog" y formnovalidate en el botón de envío.

Los botones de formulario pueden tener más atributos que los descritos al comienzo de esta sección. Si el botón incluye un atributo formaction, formenctype, formmethod, formnovalidate o formtarget, los valores establecidos en el botón que activa el envío del formulario tienen prioridad sobre los action, enctype, method y target establecidos en <form>. La validación de la restricción se realiza antes del envío del formulario, pero solo si no hay un formnovalidate en el botón de envío activado ni una novalidate en el <form>.

A fin de capturar qué botón se usó para enviar un formulario, asígnale una name. Los botones sin nombre ni valor no se envían con los datos del formulario cuando se envía el formulario.

Después de enviar el formulario

Cuando el usuario envía un formulario en línea completado, se envían los nombres y valores de los controles de formulario correspondientes. El nombre es el valor del atributo name. Los valores provienen del contenido del atributo value o del valor que ingresó o eligió el usuario. El valor de un <textarea> es su texto interno. El valor de un <select> es el value del <option> seleccionado o, si el <option> no incluye un atributo value, el valor es el texto interno de la opción seleccionada.

<form method="GET">
  <label for="student">Pick a student:</label>
  <select name="student" id="student">
    <option value="hoover">Hoover Sukhdeep</option>
    <option>Blendan Smooth</option>
    <option value="toasty">Toasty McToastface</option>
  </select>
  <input type="submit" value="Submit Form">
</form>

Si seleccionas "Hoover Sukhdeep" (o no haces nada, ya que el navegador muestra y, por lo tanto, selecciona el primer valor de la opción de forma predeterminada) y, luego, haz clic en el botón Enviar para volver a cargar esta página y se configurará la URL de la siguiente manera:

https://web.dev/learn/html/forms?student=hoover

Debido a que la segunda opción no tiene un atributo value, el texto interno se envía como el valor. Si seleccionas "Combinean Smooth" y haces clic en el botón Enviar, se volverá a cargar la página y se configurará la URL de la siguiente manera:

https://web.dev/learn/html/forms?student=Blendan+Smooth

Cuando se envía un formulario, la información enviada incluye los nombres y valores de todos los controles de formulario nombrados que tienen un name, excepto las casillas de verificación no seleccionadas, los botones de selección no seleccionados y los nombres y valores de cualquier botón que no sea el que envió el formulario. Para todos los demás controles de formulario, si el control de formulario tiene un nombre, pero no se ingresó ningún valor o no se estableció un valor predeterminado, el name del control de formulario se envía con un valor vacío.

Hay 22 tipos de entradas, por lo que no podemos abarcarlos todos. Ten en cuenta que incluir un valor es opcional y, a menudo, no es una buena idea cuando deseas que el usuario ingrese información. Para los elementos <input> en los que el usuario no puede editar el valor, siempre debes incluir un valor, incluso para los elementos de entrada con un tipo de hidden, radio, checkbox, submit, button y reset.

El uso de name únicos para los controles de formulario simplifica el procesamiento de datos del servidor y se recomienda. Las casillas de verificación y los botones de selección son excepciones a esta regla.

Botones de selección

Si alguna vez notaste que, cuando seleccionas un botón de selección dentro de un grupo de botones de selección, solo se puede seleccionar uno a la vez, esto se debe al atributo name. Para crear este efecto de solo-se-puede-seleccionar-uno, se le asigna a cada botón de selección de un grupo el mismo name.

Un name debe ser único para el grupo: si usas accidentalmente el mismo name para dos grupos separados, seleccionar un botón de selección en el segundo grupo anulará cualquier selección realizada en el primer grupo con el mismo name.

El name junto con el value del botón de selección seleccionado se envían con el formulario. Asegúrate de que cada botón de selección tenga un value relevante (y, por lo general, único). No se envían los valores de los botones de selección no seleccionados.

Puedes tener tantos grupos de radio en una página como desees, con cada grupo funcionando de forma independiente, siempre que cada uno tenga un name único para el grupo.

Si deseas cargar la página con uno de los botones de selección de un grupo con el mismo nombre seleccionado, incluye el atributo checked. Este botón de selección coincidirá con la pseudoclase CSS :default, incluso si el usuario selecciona un botón de selección diferente. El botón de selección seleccionado actualmente coincide con la pseudoclase :checked.

Si el usuario debe elegir un control de selección de un grupo de botones de selección, agrega el atributo required a al menos uno de los controles. Si incluyes required en un botón de selección de un grupo, se requiere una selección para enviar el formulario, pero no tiene que ser el botón de selección con el atributo que se selecciona para que sea válido. Además, indica claramente en el <legend> que el control de formulario es obligatorio. Más adelante, se describe el etiquetado de grupos de botones de selección junto con cada botón individual.

Casillas de verificación

Es válido que todas las casillas de verificación de un grupo tengan el mismo name. Solo las casillas de verificación seleccionadas tienen sus name y value enviados con el formulario. Si tienes varias casillas de verificación con el mismo nombre seleccionadas, se enviará el mismo nombre con valores diferentes (con suerte). Si tienes varios controles de formulario con el mismo nombre, incluso si no son todos cuadros de verificación, todos se enviarán separados por símbolos &.

Si no incluyes un value en una casilla de verificación, el valor de las casillas de verificación seleccionadas será on de forma predeterminada, lo que probablemente no sea útil. Si tienes tres casillas de verificación llamadas chk y están todas marcadas, no se podrá descifrar el envío del formulario:

https://web.dev/learn/html/forms?chk=on&chk=on&chk=on

Para que una casilla de verificación sea obligatoria, agrega el atributo required. Siempre informa al usuario cuándo debe marcarse una casilla de verificación o cuándo se requiere algún control de formulario. Agregar required a una casilla de verificación solo hace que esa casilla sea obligatoria; no afecta a otras casillas de verificación con el mismo nombre.

Etiquetas y conjuntos de campos

Para que los usuarios sepan cómo completar un formulario, este debe ser accesible. Cada control de formulario debe tener una etiqueta. También quieres etiquetar grupos de controles de formulario. Mientras que las áreas de entrada, selección y texto individuales se etiquetan con <label>, los grupos de controles de formulario se etiquetan según el contenido de <legend> de <fieldset> que los agrupa.

En los ejemplos anteriores, es posible que hayas notado que cada control de formulario, excepto el botón Enviar, tenía un <label>. Las etiquetas proporcionan controles de formulario con nombres accesibles. Los botones obtienen su nombre accesible de su contenido o valor. Todos los demás controles de formulario requieren un <label> asociado. Si no hay una etiqueta asociada, el navegador seguirá renderizando los controles de tu formulario, pero los usuarios no sabrán qué información se espera.

Para asociar explícitamente un control de formulario con un <label>, incluye el atributo for en <label>: el valor es el id del control de formulario con el que está asociado.

<label for="full_name">Your name</label>
<input type="text" id="full_name" name="name">

Asociar etiquetas con controles de formularios tiene varios beneficios. Las etiquetas permiten que los usuarios de lectores de pantalla accedan a los controles de formularios, ya que proporcionan un nombre de accesibilidad al control. Las etiquetas también son "áreas de impacto", ya que aumentan el área y hacen que el sitio sea más fácil de usar para los usuarios con problemas de destreza. Si usas un mouse, haz clic en cualquier parte de la etiqueta "Tu nombre". De esta manera, se enfoca la entrada.

Para proporcionar etiquetas implícitas, incluye el control de formulario entre las etiquetas <label> de apertura y cierre. Se puede acceder de igual manera desde la perspectiva del lector de pantalla y del dispositivo de puntero, pero no proporciona el gancho de diseño como la etiqueta explícita.

<label>Your name
  <input type="text" name="name">
</label>

Como las etiquetas son "áreas de impacto", no incluyas elementos interactivos dentro de una etiqueta explícita ni ningún otro componente interactivo que no sea el control de formulario etiquetado en una etiqueta implícita. Por ejemplo, si incluyes un vínculo en una etiqueta, mientras que el navegador renderizará el código HTML, los usuarios se confundirán si hacen clic en la etiqueta para ingresar un control de formulario, pero se los redirecciona a una página nueva.

Por lo general, el <label> va antes del control de formulario, excepto en el caso de los botones de selección y las casillas de verificación. Esto no es obligatorio. Es solo el patrón de UX común. La serie de Formularios de aprendizaje contiene información sobre el diseño de formularios.

En el caso de los grupos de botones de selección y casillas de verificación, la etiqueta proporciona el nombre accesible para el control de formulario con el que está asociado, pero el grupo de controles y sus etiquetas también necesitan una etiqueta. Para etiquetar el grupo, agrupa todos los elementos en un <fieldset>, con el <legend> que proporciona la etiqueta para el grupo.

<fieldset>
  <legend>Who is your favorite student?</legend>
  <ul>
    <li>
      <label>
        <input type="radio" value="blendan" name="machine"> Blendan Smooth
      </label>
    </li>
    <li>
      <label>
        <input type="radio" value="hoover" name="machine"> Hoover Sukhdeep
      </label>
    </li>
    <li>
      <label>
        <input type="radio" value="toasty" name="machine"> Toasty McToastface
      </label>
    </li>
  </ul>
</fieldset>

En este ejemplo, el <label> implícito asigna cada etiqueta a un botón de selección y el <legend> proporciona la etiqueta para el grupo de botones de selección. Anidar un <fieldset> dentro de otro <fieldset> es una práctica estándar. Por ejemplo, si un formulario es una encuesta de muchas preguntas divididas en grupos de preguntas relacionadas, la <fieldset> del "estudiante favorito" puede estar anidada en otra <fieldset> etiquetada como "Tus favoritos":

<fieldset>
  <legend>Your favorites:</legend>
  <ul start="6">
    <li>
      <fieldset>
        <legend>Who is your favorite student?</legend>
        <ul>
          <li>
            <!-- the rest of the code here -->

El aspecto predeterminado de estos elementos ha provocado que se usen poco, pero <legend> y <fieldset> se pueden diseñar con CSS. Además de todos los atributos globales, <fieldset> también admite los atributos name, disabled y form. Cuando inhabilitas un conjunto de campos, se inhabilitan todos los controles de formularios anidados. Ni los atributos name ni form tienen mucho uso en <fieldset>. Se puede usar name para acceder al fieldset con JavaScript, pero el fieldset en sí no se incluye en los datos enviados (se incluyen los controles de formulario nombrados anidados dentro).

Tipos de entrada y teclado dinámico

Como se mencionó antes, hay 22 tipos diferentes de entradas. En algunos casos, cuando un usuario está en un dispositivo con un teclado dinámico que se muestra solo cuando es necesario, como un teléfono, el tipo de entrada que se usa determina el tipo de teclado que se muestra. El teclado predeterminado que se muestra se puede optimizar para el tipo de entrada requerida. Por ejemplo, si escribes tel, se mostrará un teclado optimizado para ingresar números de teléfono; email incluye @ y ., y el teclado dinámico para url incluye un dos puntos y el símbolo de barra. Lamentablemente, el iPhone aún no incluye : en el teclado dinámico predeterminado para los tipos de entrada url.

Teclado para <input type="tel"> en iPhone y dos teléfonos Android diferentes:

Teclado del iPhone que muestra el tipo de entrada &quot;tel&quot;. Teclado de Android que muestra el tipo de entrada &quot;tel&quot;. Teclado de Android que muestra el tipo de entrada &quot;tel&quot;.

Teclado para <input type="email"> en iPhone y dos teléfonos Android diferentes:

Teclado de iPhone que muestra el tipo de entrada=correo electrónico. Teclado de Android que muestra el tipo de entrada=correo electrónico. Teclado de Android que muestra el tipo de entrada &quot;email&quot;.

Acceso al micrófono y la cámara

El tipo de entrada de archivo <input type="file"> permite subir archivos a través de formularios. Los archivos pueden ser de cualquier tipo y estar definidos y limitados por el atributo accept. La lista de tipos de archivos aceptables puede ser una lista separada por comas de extensiones de archivo, un tipo global o una combinación de tipos y extensiones globales. Por ejemplo, accept="video/*, .gif" acepta cualquier archivo de video o GIF animado. Usa "audio/*" para los archivos de sonido, "video/*" para los archivos de video y "image/*" para los archivos de imagen.

El atributo enumerado capture, definido en la especificación de captura de contenido multimedia, se puede usar si se va a crear un archivo multimedia nuevo con la cámara o el micrófono del usuario. Puedes establecer el valor en user para los dispositivos de entrada para el usuario o en environment para la cámara posterior o el micrófono del teléfono. Por lo general, usar capture, sin un valor, funciona porque el usuario elegirá qué dispositivo de entrada quiere usar.

<label for="avatar">A recent photo of yourself:</label>
<input type="file" capture="user" accept="image/*" name="avatar" id="avatar">

Validación integrada

Una vez más, sin incluir ningún código JavaScript, el HTML puede evitar que se envíen formularios con valores no válidos.

Hay algunos selectores CSS que coinciden con los controles de formulario según la presencia de atributos HTML, incluidos :required y :optional si el valor booleano required está establecido o no, :default si checked está codificado de forma fija y :enabled o :disabled, según si el elemento es interactivo y si el atributo disabled está presente. La pseudoclase :read-write coincide con elementos con contenteditable configurados y controles de forma que se pueden editar de forma predeterminada, como los tipos de entrada number, password y text (pero no las casillas de verificación, los botones de selección ni el tipo hidden, entre otros). Si un elemento que normalmente admite escritura tiene configurado el atributo readonly, coincidirá con :read-only en su lugar.

A medida que el usuario ingresa información en los controles de formulario, los selectores de la IU de CSS, incluidos :valid, :invalid, :in-range y :out-of-range, se activarán y desactivarán según el estado. Cuando el usuario salga de un control de formulario, coincidirá la pseudoclase :user-invalid o :user-valid, que aún no es compatible por completo.

Puedes usar CSS para proporcionar indicaciones sobre si los controles de los formularios son obligatorios y válidos cuando el usuario interactúa con él. Incluso puedes usar CSS para evitar que los usuarios puedan hacer clic en el botón de envío hasta que el formulario sea válido:

form:invalid [type="submit"] {
  opacity: 50%;
  pointer-events: none;
}

Este fragmento de CSS es un antipatrón. Si bien tu IU puede ser intuitiva y clara, muchos usuarios intentan enviar un formulario para habilitar los mensajes de error. Hacer que un botón de envío aparezca inhabilitado de esta manera no permite la validación de restricciones, una función en la que muchos usuarios confían.

El CSS aplicado se actualiza de forma continua según el estado actual de la IU. Por ejemplo, cuando incluyes tipos de entrada con restricciones, como email, number, url y tipos de fecha, si el valor no es nulo (no está vacío) y el valor actual no es un correo electrónico, número, URL, fecha o hora válidos, la pseudoclase CSS :invalid coincidirá. Esta actualización constante es diferente de la validación de restricciones HTML integrada, que solo se produce cuando el usuario intenta enviar el formulario.

La validación de restricciones integrada solo es relevante para las restricciones establecidas con atributos HTML. Si bien puedes aplicar diseño a un elemento según las pseudoclases :required y :valid/:invalid, el navegador proporciona mensajes de error que provienen de errores basados en los atributos required, pattern, min, max y hasta type cuando se envía el formulario.

Un mensaje de error que indica que se requiere un campo de selección múltiple.

Cuando intentamos enviar el formulario sin seleccionar al estudiante favorito requerido, la validación de restricciones impide el envío del formulario debido a un error validityState.valueMissing.

Si alguna de las propiedades de validityState muestra true, se bloquea el envío y el navegador muestra un mensaje de error en el primer control de formulario incorrecto, lo que le enfoca. Cuando el usuario active el envío de un formulario y haya valores no válidos, el primer control de formulario no válido mostrará un mensaje de error y recibirá el enfoque. Si un control obligatorio no tiene un valor establecido, si un valor numérico está fuera de rango o si un valor no es del tipo que requiere el atributo type, el formulario no se validará ni enviará, y aparecerá un mensaje de error.

Si un valor de number, fecha o hora está por debajo del valor mínimo de min establecido o por encima del valor máximo de max establecido, el control será :out-of-range (y :invalid), y se le informará al usuario sobre el error valididityState.rangeUnderflow, validityState.rangeOverflow cuando intente enviar el formulario. Si el valor está fuera de paso con el valor step, ya sea establecido de forma explícita o de forma predeterminada en 1, el control será :out-of-range (y :invalid) y se generará un error validityState.stepMismatch. El error aparece como una burbuja y, de forma predeterminada, proporciona información útil para corregir el error.

Hay atributos similares para la longitud de los valores: los atributos minlength y maxlength alertarán al usuario sobre un error con validityState.tooLong o validityState.tooShort cuando se envíe el contenido. El maxlength también impide que el usuario ingrese demasiados caracteres.

El uso del atributo maxlength puede generar una experiencia del usuario deficiente. Por lo general, es mejor permitir que el usuario ingrese más de la longitud de caracteres permitida proporcionando un contador, de forma opcional, en forma de un elemento <output>, que no se envía con el formulario, lo que le permite editar el texto hasta que el resultado muestre que no se superó la longitud máxima permitida. El maxlength se puede incluir en tu código HTML. Como todo lo que analizamos, funciona sin JavaScript. Luego, durante la carga, se puede usar el valor del atributo maxlength para crear este contador de caracteres en JavaScript.

Algunos tipos de entrada parecen tener restricciones predeterminadas, pero no es así. Por ejemplo, el tipo de entrada tel proporciona un teclado numérico en dispositivos con teclados dinámicos, pero no restringe valores válidos. Para este y otros tipos de entradas, existe el atributo pattern. Puedes especificar una expresión regular con la que debe coincidir el valor para que se considere válido. Si un valor es una string vacía y el valor no es obligatorio, no se generará un error validityState.patternMismatch. Si es obligatorio y está vacío, se mostrará al usuario el mensaje de error predeterminado de validityState.valueMissing, en lugar de patternMismatch.

En el caso de los correos electrónicos, es probable que validityState.typeMismatch sea demasiado tolerante para tus necesidades. Es probable que desees incluir el atributo pattern para que las direcciones de correo electrónico de la intranet sin un TLD no se acepten como válidas. El atributo pattern permite proporcionar una expresión regular con la que debe coincidir el valor. Cuando necesites una coincidencia de patrón, asegúrate de que sea muy claro para el usuario lo que se espera.

Todo esto se puede hacer sin una sola línea de JavaScript, pero como es una API de HTML, puedes usar JavaScript para incluir mensajes personalizados durante la validación de restricciones. También puedes usar JavaScript para actualizar la cantidad de caracteres que quedan, mostrar una barra de progreso para la seguridad de la contraseña o cualquier otra forma de mejorar de forma dinámica la finalización.

Ejemplo

Este ejemplo tiene un formulario dentro de una <dialog> con un <form> anidado con tres controles de formulario y dos botones de envío, con instrucciones y etiquetas claras.

El primer botón de envío cierra el diálogo. Usa formmethod="dialog" para anular el método predeterminado del formulario y cerrar el <dialog> sin enviar los datos ni borrarlos. También debes incluir formnovalidate; de lo contrario, el navegador intentará validar que todos los campos obligatorios tengan un valor. Es posible que el usuario desee cerrar el diálogo y el formulario sin ingresar ningún dato. La validación evitaría esto. Incluye aria-label="close" porque “X” es una señal visual conocida, pero no es una etiqueta descriptiva.

Todos los controles de formulario tienen etiquetas implícitas, por lo que no necesitas incluir atributos id ni for. Los elementos de entrada tienen el atributo obligatorio que los hace obligatorios. La entrada numérica tiene el step configurado de forma explícita para demostrar cómo se incluye step. Como step tiene el valor predeterminado 1, se puede omitir este atributo.

<select> tiene un valor predeterminado, por lo que el atributo required no es necesario. En lugar de incluir el atributo value en cada opción, el valor predeterminado es el texto interno.

El botón de envío al final establece el método de los formularios en POST. Cuando se haga clic, se verificará la validez de cada valor. Si todos los valores son válidos, se enviarán los datos del formulario, se cerrará el diálogo y es posible que la página redireccione a thankyou.php, que es la URL de la acción. Si falta algún valor o si el valor numérico tiene una discrepancia de pasos o está fuera de rango, aparecerá un mensaje de error definido por el navegador relevante, no se enviará el formulario y no se cerrará el diálogo. Los mensajes de error predeterminados se pueden personalizar con el método validityState.setCustomValidity('message here'). Solo ten en cuenta que si configuras un mensaje personalizado, este debe establecerse explícitamente en la cadena vacía cuando todo sea válido o no se envíe el formulario.

Otras consideraciones

Hay una sección completa dedicada a ayudar a los usuarios a ingresar los datos correctos en los formularios. Para que el usuario tenga una buena experiencia, es importante evitar que cometan errores incluyendo instrucciones y proporcionando sugerencias según sea necesario. Si bien en esta sección se explica cómo el HTML solo puede proporcionar validación del cliente, la validación debe ser del cliente y del servidor. La validación se puede proporcionar de formas discretas durante el proceso de completar el formulario, como agregar una marca de verificación cuando el valor es correcto. Sin embargo, no proporciones mensajes de error antes de que se complete el control del formulario. Si el usuario comete un error, infórmale dónde está y qué hizo mal.

Cuando diseñas formularios, es importante recordar que existen diferentes estándares de nombres, formatos de direcciones y mucho más en todo el mundo. Una persona puede tener una sola letra como apellido (o no tener apellido), no tener un código postal, tener una dirección de tres líneas o no tener una dirección. Es posible que esta persona esté viendo una versión traducida de tu formulario.

Los controles de formulario, sus etiquetas y los mensajes de error deben ser visibles en la pantalla, ser precisos y significativos, determinarse de manera programática y asociarse de forma programática con el elemento o grupo del formulario correspondiente. El atributo autocomplete puede y debe usarse para permitir que los formularios se completen más rápido y mejorar la accesibilidad.

El HTML proporciona todas las herramientas para que los controles de formulario básicos sean accesibles. Cuanto más interactivo sea un elemento o proceso de formulario, más atención se debe prestar a la accesibilidad con respecto a la administración del enfoque, la configuración y la actualización de los nombres, roles y valores de ARIA, cuando sea necesario, y los anuncios en vivo de ARIA según sea necesario. Sin embargo, como aprendimos aquí, solo con HTML, puedes avanzar mucho en tu objetivo de accesibilidad y validez sin recurrir a ARIA ni JavaScript.

Verifica tu comprensión

Pon a prueba tus conocimientos sobre formularios.

¿Cómo haces que los botones de selección formen parte del mismo grupo?

Asígnales el mismo valor del atributo id.
Colócalos todos dentro de un conjunto de campos.
Asígnales el mismo valor del atributo name.

¿Qué elemento HTML se usa para indicarle al usuario para qué sirve este campo de formulario?

<title>
<h1>
<label>