Formularios

Intermedio
HTML
HTML
Actualizado: 26/08/2025

Elementos de entrada básicos

Los formularios HTML constituyen la base fundamental para recopilar información del usuario en páginas web. Permiten crear interfaces interactivas donde los usuarios pueden introducir datos, seleccionar opciones y enviar información al servidor.

Un formulario se define mediante la etiqueta **<form>**, que actúa como contenedor para todos los elementos de entrada. Esta etiqueta establece el contexto necesario para que los navegadores procesen correctamente los datos introducidos por el usuario.

<form>
  <!-- Aquí van los elementos de entrada -->
</form>

Estructura básica del elemento form

El elemento **<form>** acepta varios atributos que definen cómo se procesarán los datos:

<form action="/procesar-datos" method="post">
  <!-- Contenido del formulario -->
</form>
  • El atributo **action** especifica la URL donde se enviarán los datos
  • El atributo **method** define el método HTTP (generalmente get o post)

El elemento input para texto

El elemento **<input>** es la base de la mayoría de campos de entrada. Su comportamiento varía según el valor del atributo type. Para entrada de texto básica utilizamos type="text":

<input type="text" name="nombre" id="nombre">

Los atributos esenciales del elemento input incluyen:

  • **name**: identifica el campo cuando se envían los datos
  • **id**: permite asociar el campo con etiquetas y facilita el acceso desde CSS y JavaScript
  • **placeholder**: muestra texto de ayuda dentro del campo
  • **required**: marca el campo como obligatorio
<input type="text" name="apellidos" id="apellidos" placeholder="Introduce tus apellidos" required>

Etiquetas descriptivas con label

El elemento **<label>** proporciona descripciones legibles para los campos de entrada. Mejora significativamente la accesibilidad y la experiencia de usuario:

<label for="email">Correo electrónico:</label>
<input type="email" name="email" id="email">

También puedes anidar el input dentro del label, eliminando la necesidad del atributo for:

<label>
  Teléfono:
  <input type="text" name="telefono">
</label>

Campos de contraseña

Para entrada de contraseñas utilizamos type="password", que oculta automáticamente los caracteres introducidos:

<label for="password">Contraseña:</label>
<input type="password" name="password" id="password" required>

Áreas de texto multilínea

El elemento **<textarea>** permite introducir texto extenso en múltiples líneas. A diferencia de input, textarea utiliza etiquetas de apertura y cierre:

<label for="comentarios">Comentarios:</label>
<textarea name="comentarios" id="comentarios" rows="4" cols="50"></textarea>

Los atributos **rows** y **cols** definen las dimensiones iniciales del área de texto, aunque pueden ajustarse con CSS.

Listas desplegables con select

El elemento **<select>** crea menús desplegables que permiten elegir entre opciones predefinidas:

<label for="pais">País:</label>
<select name="pais" id="pais">
  <option value="es">España</option>
  <option value="fr">Francia</option>
  <option value="it">Italia</option>
</select>

Cada opción se define con **<option>**, donde el atributo value especifica el valor que se enviará al servidor.

Botones de envío

Los botones de envío procesan los datos del formulario. Utilizamos type="submit" para crear botones que envían automáticamente el formulario:

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

También puedes usar input para crear botones:

<input type="submit" value="Registrarse">

Ejemplo práctico completo

<form action="/registro" method="post">
  <label for="nombre">Nombre completo:</label>
  <input type="text" name="nombre" id="nombre" required>
  
  <label for="email">Email:</label>
  <input type="email" name="email" id="email" required>
  
  <label for="password">Contraseña:</label>
  <input type="password" name="password" id="password" required>
  
  <label for="ciudad">Ciudad:</label>
  <select name="ciudad" id="ciudad">
    <option value="">Selecciona una ciudad</option>
    <option value="madrid">Madrid</option>
    <option value="barcelona">Barcelona</option>
    <option value="valencia">Valencia</option>
  </select>
  
  <label for="biografia">Biografía:</label>
  <textarea name="biografia" id="biografia" rows="3" placeholder="Cuéntanos algo sobre ti"></textarea>
  
  <button type="submit">Crear cuenta</button>
</form>

Este ejemplo muestra la estructura básica de un formulario de registro que combina todos los elementos fundamentales. Cada campo tiene su etiqueta correspondiente, atributos apropiados para la funcionalidad requerida y una organización lógica que facilita su comprensión y uso.

Tipos de input avanzados

HTML ofrece una amplia variedad de tipos de entrada especializados que van más allá de los campos de texto básicos. Estos elementos proporcionan interfaces nativas optimizadas para diferentes tipos de datos, mejorando la experiencia de usuario y facilitando la validación automática.

Campos numéricos

El tipo **number** está diseñado específicamente para la entrada de valores numéricos. Proporciona controles nativos para incrementar y decrementar valores:

<label for="edad">Edad:</label>
<input type="number" name="edad" id="edad" min="18" max="100" step="1">

Los atributos específicos para campos numéricos incluyen:

  • **min**: valor mínimo permitido
  • **max**: valor máximo permitido
  • **step**: incremento entre valores válidos
<label for="precio">Precio (€):</label>
<input type="number" name="precio" id="precio" min="0" max="9999.99" step="0.01">

Controles deslizantes con range

El tipo **range** crea controles deslizantes ideales para seleccionar valores dentro de un rango específico:

<label for="volumen">Volumen:</label>
<input type="range" name="volumen" id="volumen" min="0" max="100" value="50">

Puedes mostrar el valor actual combinando el control con un elemento que refleje la selección:

<label for="satisfaccion">Nivel de satisfacción: <span id="valor-satisfaccion">5</span></label>
<input type="range" name="satisfaccion" id="satisfaccion" min="1" max="10" value="5">

Campos de fecha y hora

HTML incluye varios tipos especializados para fechas y horas que proporcionan selectores nativos optimizados:

1 - Campo de fecha:

<label for="fecha-nacimiento">Fecha de nacimiento:</label>
<input type="date" name="fecha-nacimiento" id="fecha-nacimiento">

2 - Campo de hora:

<label for="hora-cita">Hora de la cita:</label>
<input type="time" name="hora-cita" id="hora-cita">

3 - Fecha y hora combinadas:

<label for="fecha-evento">Fecha y hora del evento:</label>
<input type="datetime-local" name="fecha-evento" id="fecha-evento">

Selector de color

El tipo **color** proporciona un selector de colores nativo que permite a los usuarios elegir colores de manera visual:

<label for="color-favorito">Color favorito:</label>
<input type="color" name="color-favorito" id="color-favorito" value="#ff0000">

El atributo **value** debe especificar un color en formato hexadecimal. El selector mostrará este color como valor inicial.

Subida de archivos

El tipo **file** permite a los usuarios seleccionar y cargar archivos desde su dispositivo:

<label for="curriculum">Subir currículum:</label>
<input type="file" name="curriculum" id="curriculum" accept=".pdf,.doc,.docx">

El atributo **accept** especifica qué tipos de archivo son válidos, mejorando la experiencia de usuario al filtrar automáticamente las opciones.

<label for="foto-perfil">Foto de perfil:</label>
<input type="file" name="foto-perfil" id="foto-perfil" accept="image/*">

Campos especializados para URLs y teléfonos

1 - Campo URL:

<label for="sitio-web">Sitio web:</label>
<input type="url" name="sitio-web" id="sitio-web" placeholder="https://ejemplo.com">

2 - Campo teléfono:

<label for="telefono">Teléfono:</label>
<input type="tel" name="telefono" id="telefono" placeholder="+34 123 456 789">

Campo de búsqueda

El tipo **search** está optimizado para funciones de búsqueda y puede mostrar comportamientos específicos como botones de borrado:

<label for="buscar">Buscar productos:</label>
<input type="search" name="buscar" id="buscar" placeholder="Introduce tu búsqueda">

Casillas de verificación

Las casillas de verificación (checkbox) permiten selecciones múltiples independientes:

<fieldset>
  <legend>Intereses:</legend>
  
  <label>
    <input type="checkbox" name="intereses" value="programacion">
    Programación
  </label>
  
  <label>
    <input type="checkbox" name="intereses" value="diseño">
    Diseño
  </label>
  
  <label>
    <input type="checkbox" name="intereses" value="marketing">
    Marketing
  </label>
</fieldset>

Botones de radio

Los botones de radio (radio) permiten seleccionar una única opción de un grupo relacionado:

<fieldset>
  <legend>Experiencia en programación:</legend>
  
  <label>
    <input type="radio" name="experiencia" value="principiante">
    Principiante
  </label>
  
  <label>
    <input type="radio" name="experiencia" value="intermedio">
    Intermedio
  </label>
  
  <label>
    <input type="radio" name="experiencia" value="avanzado">
    Avanzado
  </label>
</fieldset>

El atributo **name** debe ser idéntico en todos los botones de radio del mismo grupo para que funcionen correctamente como opciones mutuamente excluyentes.

Agrupación con fieldset y legend

El elemento **<fieldset>** agrupa campos relacionados, mientras que <legend> proporciona un título descriptivo para el grupo:

<fieldset>
  <legend>Información de contacto</legend>
  
  <label for="email-contacto">Email:</label>
  <input type="email" name="email-contacto" id="email-contacto" required>
  
  <label for="telefono-contacto">Teléfono:</label>
  <input type="tel" name="telefono-contacto" id="telefono-contacto">
</fieldset>

Ejemplo práctico integrado

<form action="/perfil" method="post" enctype="multipart/form-data">
  <fieldset>
    <legend>Configuración de perfil</legend>
    
    <label for="avatar">Avatar:</label>
    <input type="file" name="avatar" id="avatar" accept="image/*">
    
    <label for="edad-usuario">Edad:</label>
    <input type="number" name="edad-usuario" id="edad-usuario" min="16" max="120">
    
    <label for="fecha-registro">Fecha de registro:</label>
    <input type="date" name="fecha-registro" id="fecha-registro">
    
    <label for="color-tema">Color del tema:</label>
    <input type="color" name="color-tema" id="color-tema" value="#3498db">
  </fieldset>
  
  <fieldset>
    <legend>Preferencias</legend>
    
    <label>
      <input type="checkbox" name="notificaciones" value="email">
      Recibir notificaciones por email
    </label>
    
    <label>
      <input type="checkbox" name="notificaciones" value="sms">
      Recibir notificaciones por SMS
    </label>
    
    <label for="frecuencia">Frecuencia de notificaciones:</label>
    <input type="range" name="frecuencia" id="frecuencia" min="1" max="5" value="3">
  </fieldset>
  
  <button type="submit">Guardar configuración</button>
</form>

Este ejemplo muestra cómo combinar diferentes tipos de entrada para crear formularios ricos y funcionales. Cada tipo de campo está optimizado para su propósito específico, proporcionando la mejor experiencia de usuario posible mientras facilita la validación y el procesamiento de datos.

Validación de formularios

La validación de formularios en HTML permite verificar automáticamente que los datos introducidos por el usuario cumplen ciertos criterios antes del envío. HTML proporciona mecanismos nativos de validación que funcionan directamente en el navegador, mejorando la experiencia de usuario y reduciendo errores de entrada.

Validación con el atributo required

El atributo **required** marca campos como obligatorios, impidiendo el envío del formulario si están vacíos:

<label for="nombre-completo">Nombre completo:</label>
<input type="text" name="nombre-completo" id="nombre-completo" required>

<label for="email-principal">Email:</label>
<input type="email" name="email-principal" id="email-principal" required>

Este atributo funciona con todos los tipos de entrada y muestra automáticamente mensajes de error cuando el usuario intenta enviar el formulario sin completar los campos obligatorios.

Validación de longitud de texto

Los atributos **minlength** y **maxlength** controlan la longitud mínima y máxima del texto introducido:

<label for="usuario">Nombre de usuario:</label>
<input type="text" name="usuario" id="usuario" minlength="3" maxlength="20" required>

<label for="password-segura">Contraseña:</label>
<input type="password" name="password-segura" id="password-segura" minlength="8" maxlength="50" required>

Para áreas de texto también puedes aplicar estas restricciones:

<label for="descripcion">Descripción del proyecto:</label>
<textarea name="descripcion" id="descripcion" minlength="50" maxlength="500" required></textarea>

Validación de rangos numéricos

Los campos numéricos pueden validarse usando los atributos min y max:

<label for="edad-minima">Edad:</label>
<input type="number" name="edad-minima" id="edad-minima" min="18" max="65" required>

<label for="puntuacion">Puntuación (1-10):</label>
<input type="number" name="puntuacion" id="puntuacion" min="1" max="10" step="1" required>

Validación automática por tipo de entrada

Ciertos tipos de input proporcionan validación automática sin necesidad de atributos adicionales:

1 - Validación de email:

<label for="correo-usuario">Correo electrónico:</label>
<input type="email" name="correo-usuario" id="correo-usuario" required>

2 - Validación de URL:

<label for="sitio-personal">Sitio web personal:</label>
<input type="url" name="sitio-personal" id="sitio-personal" required>

Validación de fechas

Los campos de fecha permiten establecer rangos válidos:

<label for="fecha-inicio">Fecha de inicio:</label>
<input type="date" name="fecha-inicio" id="fecha-inicio" min="2024-01-01" max="2024-12-31" required>

<label for="hora-reunion">Hora de reunión:</label>
<input type="time" name="hora-reunion" id="hora-reunion" min="09:00" max="18:00" required>

Validación de archivos

Para campos de archivo puedes restringir los tipos permitidos y el tamaño:

<label for="documento">Documento PDF:</label>
<input type="file" name="documento" id="documento" accept=".pdf" required>

<label for="imagen-perfil">Imagen de perfil:</label>
<input type="file" name="imagen-perfil" id="imagen-perfil" accept="image/jpeg,image/png,image/gif" required>

Desactivar validación

El atributo **novalidate** en el elemento form desactiva toda la validación HTML:

<form action="/borrador" method="post" novalidate>
  <label for="email-borrador">Email:</label>
  <input type="email" name="email-borrador" id="email-borrador" required>
  
  <button type="submit">Guardar borrador</button>
</form>

También puedes desactivar validación en botones específicos usando formnovalidate:

<form action="/guardar" method="post">
  <label for="email-trabajo">Email de trabajo:</label>
  <input type="email" name="email-trabajo" id="email-trabajo" required>
  
  <button type="submit">Enviar</button>
  <button type="submit" formnovalidate formaction="/borrador">Guardar como borrador</button>
</form>

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en HTML

Documentación oficial de HTML
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, HTML es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de HTML

Explora más contenido relacionado con HTML y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la estructura básica y los elementos fundamentales de un formulario HTML.
  • Conocer los diferentes tipos de campos de entrada y sus atributos específicos.
  • Aprender a agrupar y organizar campos con fieldset y legend para mejorar la accesibilidad.
  • Implementar validaciones nativas en formularios para asegurar la calidad de los datos.
  • Combinar múltiples tipos de inputs y validaciones para crear formularios completos y funcionales.