Formularios HTML: los elementos básicos para crear un formulario

Aprende lo básico de los formularios HTML. Crea formularios accesibles con buena estructura, tipos de campo, validación y envío de datos.

Borrador

Cuando creas un formulario, usas frameworks o creadores de formularios. Pero por debajo, todos usan formularios HTML. Si entiendes cómo funcionan los formularios HTML, entiendes todo lo demás. No dependes de ninguna herramienta ni framework. Conoces lo esencial.

Este artículo explica el elemento form de HTML, los tipos de campo, las etiquetas, la validación y cómo se envían realmente los formularios. Sin frameworks. Sin librerías. Solo HTML y los principios sobre los que se construye todo lo demás.

El elemento form de HTML

Un formulario es un elemento HTML que envuelve los campos y envía sus datos a algún sitio. La estructura básica es:

<form action="/submit" method="POST">

<input type="text" name="email">

<button type="submit">Send</button>

</form>

Importan tres atributos. El atributo action indica adónde enviar los datos. "/submit" significa enviar con POST al endpoint /submit de tu servidor. Si action está vacío, el formulario se envía a la página actual. El atributo method indica cómo viajan los datos. POST envía los datos en el cuerpo de la petición (seguro, oculto en la URL). GET añade los datos a la URL (poco seguro para datos sensibles, útil para búsquedas). El atributo enctype solo hace falta para subir archivos. Usa enctype="multipart/form-data" cuando tu formulario tenga un campo de archivo.

Todo lo que hay dentro de las etiquetas del formulario forma parte del envío. Cuando el usuario hace clic en el botón de enviar, el navegador recoge todos los campos con nombre y los manda a la URL de action con el método indicado.

Tipos de campo y qué hacen

text

<input type="text" name="first_name">

Un campo de texto de una sola línea. El navegador muestra un cuadro de texto básico. Sin validación. Se permite cualquier carácter.

email

<input type="email" name="email">

Un campo para direcciones de email. En el ordenador parece un campo de texto. En el móvil, el navegador muestra un teclado de email. Al enviar, el navegador comprueba que el valor parezca un email (que tenga una @). Es solo una validación básica.

password

<input type="password" name="password">

Texto que se oculta con puntos o asteriscos mientras escribes. El valor se transmite igualmente en texto plano, así que usa siempre HTTPS en los formularios con campos de contraseña.

number

<input type="number" name="age">

En el ordenador, un campo de texto que solo acepta números. En el móvil, el navegador muestra un teclado numérico. El navegador impide escribir algo que no sea un número.

date

<input type="date" name="birth_date">

Un selector de fecha. En los navegadores y dispositivos compatibles, al hacer clic en el campo se abre un calendario. El valor tiene el formato AAAA-MM-DD.

checkbox

<input type="checkbox" name="agree" value="yes">

Una casilla que se activa y se desactiva. Si está marcada, el valor del campo se envía al enviar el formulario. Si no está marcada, el campo no se envía en absoluto.

radio

<input type="radio" name="plan" value="starter"> Starter

<input type="radio" name="plan" value="pro"> Pro

Varios botones de opción con el mismo nombre funcionan como un grupo. Solo se puede elegir uno a la vez. Al enviar, se manda el valor del elegido.

select (desplegable)

<select name="country">

<option value="us">United States</option>

<option value="ca">Canada</option>

</select>

Un menú desplegable. Al enviar, se manda el valor de la opción elegida.

textarea

<textarea name="message"></textarea>

Un campo de texto de varias líneas. Los usuarios pueden escribir párrafos. El valor incluye los saltos de línea.

file

<input type="file" name="resume">

Un botón que abre el selector de archivos del dispositivo. El archivo elegido se envía al servidor. Requiere enctype="multipart/form-data" en el elemento form.

hidden

<input type="hidden" name="user_id" value="12345">

Un campo que no se muestra pero se envía con el formulario. Sirve para datos de seguimiento que deben incluirse y que el usuario no debe cambiar.

Etiquetas y accesibilidad

Empareja siempre los campos con etiquetas.

<label for="email">Email address</label>

<input type="email" id="email" name="email">

El atributo for de la etiqueta debe coincidir con el id del campo. Si lo haces bien:

Los lectores de pantalla anuncian la etiqueta y el campo juntos, al hacer clic en la etiqueta el cursor pasa al campo, y los usuarios de móvil tienen una zona táctil más grande.

Nunca te saltes las etiquetas. Si necesitas ocultar una etiqueta a la vista, ocúltala con CSS pero déjala en el HTML. Esto se llama una etiqueta "visualmente oculta".

Cómo agrupar campos relacionados

Para campos relacionados, usa fieldset y legend.

<fieldset>

<legend>Shipping address</legend>

<input type="text" name="street">

<input type="text" name="city">

</fieldset>

El elemento legend anuncia el grupo a los lectores de pantalla. Los fieldset ayudan a organizar los botones de opción y las casillas, tanto a la vista como en la estructura.

Envío del formulario y métodos HTTP

Cuando el usuario hace clic en el botón de enviar, el navegador recoge todos los campos con nombre, codifica los datos (application/x-www-form-urlencoded por defecto), envía una petición HTTP a la URL de action con el método (POST o GET) y espera una respuesta.

El servidor recibe la petición y puede procesar los datos. Los datos llegan como pares clave-valor. Si el método del formulario es POST y action es "/submit", la petición se ve así. POST /submit HTTP/1.1 con Content-Type igual a application/x-www-form-urlencoded, y luego los datos aparecen como email=user@example.com&name=John.

El servidor interpreta estos datos y responde. Si la respuesta es una página, el navegador la carga. Si la respuesta es una redirección, el navegador va a la nueva URL.

Validación en el navegador

HTML tiene atributos de validación integrados. El navegador los comprueba antes de enviar el formulario.

required

<input type="text" name="email" required>

El campo debe tener un valor. Si se deja vacío, el formulario no se envía y el navegador muestra un error.

minlength y maxlength

<input type="password" name="password" minlength="8" maxlength="128">

El valor debe tener un número de caracteres entre los indicados.

min y max

<input type="number" name="age" min="18" max="120">

En los campos numéricos, el valor debe estar dentro del rango.

pattern

<input type="text" name="zip_code" pattern="[0-9]{5}">

Una expresión regular con la que debe coincidir el valor. Un código postal de cinco cifras coincide con [0-9]{5}.

La validación en el navegador es una comodidad para los usuarios. Evita que envíen datos no válidos y vean un error del servidor. Pero nunca confíes en ella para la seguridad. Valida siempre también en el servidor.

La diferencia entre type="submit" y type="button"

<button type="submit">Send</button>

<button type="button">Save</button>

Un botón con type="submit" envía el formulario al hacer clic. Un botón con type="button" no hace nada por defecto. Usa type="button" cuando quieras asociarle controladores de eventos de JavaScript.

Muchos desarrolladores usan <button> sin indicar el tipo. Por defecto es type="submit", que suele ser lo que quieres. Pero sé explícito para evitar sorpresas.

Por qué conviene entender los formularios HTML

Si usas un framework de JavaScript, estás construyendo sobre formularios HTML. Los frameworks ocultan los detalles, pero los principios de fondo son los mismos. Un formulario sigue enviándose a un endpoint. La validación sigue siendo necesaria. El servidor sigue teniendo que gestionar los datos.

Cuando algo falla en el manejo de tu formulario, entender HTML te ayuda a depurarlo. Sabes de dónde salen los datos, cómo se codifican y qué debería recibir el servidor. Esta es la base.

La mayoría de las aplicaciones web modernas ya no usa el envío tradicional de formularios. Usan JavaScript para interceptar el formulario, validarlo y enviar los datos con _blocked_ o con una librería de peticiones. Pero conocer primero la forma HTML hace que esos patrones tengan sentido.

Cómo usa estos principios el creador de formularios de WEMASY

Por debajo, el creador de formularios de WEMASY genera formularios HTML accesibles con estos mismos elementos. Las etiquetas van emparejadas con los campos. La validación se hace tanto en el navegador como en el servidor. Los datos del formulario se envían de forma segura. Si exportas o personalizas un formulario de WEMASY, trabajas con formularios HTML construidos sobre estos fundamentos.

Consulta la página de precios de WEMASY para ver las funciones de formularios y las opciones de personalización.

Preguntas frecuentes

¿Debo usar GET o POST para enviar mi formulario?
Usa POST en cualquier formulario que cambie datos, envíe información sensible o suba archivos. Usa GET solo en formularios de búsqueda, donde la consulta puede verse en la URL. GET es menos seguro y tiene límites de longitud de URL. POST es la opción segura para la mayoría de los formularios. Con el creador de webs de WEMASY, puedes configurarlo directamente en tu web.
¿Basta con validar en el navegador o necesito también validar en el servidor?
Valida siempre en el servidor. La validación en el navegador es para mejorar la experiencia de usuario. Alguien puede desactivar JavaScript o saltarse las comprobaciones del navegador. La seguridad real está en la validación del servidor. Haz las dos.
¿Cómo envío un formulario con JavaScript en lugar del envío por defecto?
Escucha el evento submit con addEventListener, llama a event.preventDefault() y usa _blocked_ u otra librería de peticiones para enviar los datos. Así puedes validar, transformar o añadir datos extra antes de enviar.
¿Cuál es la diferencia entre los datos de formulario y JSON?
Por defecto, los formularios envían los datos como application/x-www-form-urlencoded (pares clave-valor). JSON es otro formato. Cuando interceptas un formulario con JavaScript y usas _blocked_ para enviar JSON, cambias el tipo de contenido. El servidor necesita saber qué formato esperar.
¿Por qué debo usar elementos label en lugar de poner texto junto a los campos?
Las etiquetas mejoran la accesibilidad para los lectores de pantalla y la navegación con teclado. También crean una zona de clic más grande en el móvil. Si tienes que ocultar una etiqueta a la vista, ocúltala con CSS pero déjala en el HTML para que la tecnología de apoyo pueda encontrarla.
¿Debo preocuparme por la protección CSRF en los formularios?
Sí. Si tu formulario cambia datos (crea, actualiza o borra), usa un token CSRF para evitar la falsificación de peticiones entre sitios. Incluye un campo oculto con un token único generado por el servidor. Verifica el token cuando se envíe el formulario.

Ponlo en práctica
en tu propia web.

Empieza gratis con WEMASY y crea tu web en pocos minutos.