Formularios en HTML: Una Guía para Principiantes sobre el Elemento <form>
Aprende a crear formularios HTML interactivos con tipos de input, etiquetas, botones y validación básica. Domina la accesibilidad de formularios y mejores prácticas.
Aprende a crear formularios HTML interactivos con tipos de input, etiquetas, botones y validación básica. Domina la accesibilidad de formularios y mejores prácticas.
<form>
?El elemento <form>
es un contenedor que envuelve todos los controles de formulario y define cómo se deben procesar los datos del formulario. Actúa como la base para recopilar la entrada del usuario y enviarla a un servidor.
<form action="/enviar" method="POST">
<!-- Los controles del formulario van aquí -->
<input type="text" name="usuario" required>
<button type="submit">Enviar</button>
</form>
action
: Especifica dónde enviar los datos del formulario cuando se envíamethod
: Define cómo enviar los datos (GET o POST)enctype
: Especifica cómo se deben codificar los datos del formulario (importante para cargas de archivos)<form action="/contacto" method="POST" enctype="multipart/form-data">
<!-- Formulario para cargas de archivos -->
</form>
HTML5 introdujo numerosos tipos de input que proporcionan mejor experiencia de usuario y validación incorporada. Exploremos los más comúnmente utilizados:
<!-- Input de texto básico -->
<input type="text" name="nombre-completo" placeholder="Ingresa tu nombre completo">
<!-- Input de contraseña (oculta caracteres) -->
<input type="password" name="contraseña" placeholder="Ingresa contraseña">
<!-- Input de email (con validación incorporada) -->
<input type="email" name="email" placeholder="usuario@ejemplo.com">
<!-- Input de número de teléfono -->
<input type="tel" name="telefono" placeholder="+34 123 456 789">
<!-- Input de URL -->
<input type="url" name="sitio-web" placeholder="https://ejemplo.com">
<!-- Input de número con valores mín/máx -->
<input type="number" name="edad" min="18" max="100" step="1">
<!-- Selector de fecha -->
<input type="date" name="fecha-nacimiento">
<!-- Selector de hora -->
<input type="time" name="cita">
<!-- Selector de color -->
<input type="color" name="color-tema" value="#ff0000">
<!-- Carga de archivos -->
<input type="file" name="curriculum" accept=".pdf,.doc,.docx">
<!-- Botones de radio (selección única) -->
<input type="radio" name="genero" value="masculino" id="masculino">
<input type="radio" name="genero" value="femenino" id="femenino">
<!-- Casillas de verificación (selecciones múltiples) -->
<input type="checkbox" name="intereses" value="programacion" id="programacion">
<input type="checkbox" name="intereses" value="diseño" id="diseño">
<!-- Control deslizante de rango -->
<input type="range" name="satisfaccion" min="1" max="10" value="5">
Las etiquetas son cruciales para la accesibilidad de formularios. Proporcionan contexto para lectores de pantalla y mejoran la usabilidad para todos los usuarios.
<!-- Método 1: Usando atributo 'for' -->
<label for="usuario">Nombre de usuario:</label>
<input type="text" id="usuario" name="usuario" required>
<!-- Método 2: Envolviendo input dentro de label -->
<label>
Dirección de Email:
<input type="email" name="email" required>
</label>
<form action="/registro" method="POST">
<fieldset>
<legend>Información Personal</legend>
<div class="form-group">
<label for="nombre">Nombre *</label>
<input type="text" id="nombre" name="nombre" required
aria-describedby="nombre-ayuda">
<small id="nombre-ayuda">Ingresa tu nombre legal</small>
</div>
<div class="form-group">
<label for="email">Dirección de Email *</label>
<input type="email" id="email" name="email" required
aria-describedby="email-ayuda">
<small id="email-ayuda">Nunca compartiremos tu email</small>
</div>
<div class="form-group">
<label for="telefono">Número de Teléfono</label>
<input type="tel" id="telefono" name="telefono"
aria-describedby="telefono-ayuda">
<small id="telefono-ayuda">Opcional: Incluye código de país</small>
</div>
</fieldset>
</form>
Los botones controlan el comportamiento del formulario y proporcionan acciones claras para los usuarios.
<!-- Botón de envío (envía el formulario) -->
<button type="submit">Crear Cuenta</button>
<!-- Botón de reinicio (limpia datos del formulario) -->
<button type="reset">Limpiar Formulario</button>
<!-- Botón regular (para interacciones JavaScript) -->
<button type="button" onclick="mostrarAyuda()">¿Necesitas Ayuda?</button>
<!-- Usando elemento input -->
<input type="submit" value="Enviar Formulario">
<!-- Usando elemento button (más flexible) -->
<button type="submit">
<span>Enviar Formulario</span>
<svg><!-- icono --></svg>
</button>
HTML5 proporciona validación incorporada que funciona sin JavaScript, mejorando la experiencia del usuario y la calidad de los datos.
<input type="text" name="usuario" required>
<input type="email" name="email" required>
<select name="pais" required>
<option value="">Elige un país</option>
<option value="es">España</option>
<option value="mx">México</option>
</select>
<!-- Patrón de número de teléfono -->
<input type="tel" name="telefono"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{3}"
placeholder="123-456-789">
<!-- Patrón personalizado de nombre de usuario -->
<input type="text" name="usuario"
pattern="[a-zA-Z0-9_]{3,16}"
title="El nombre de usuario debe tener 3-16 caracteres, solo letras, números y guiones bajos">
<!-- Límites de longitud de texto -->
<input type="text" name="titulo" minlength="5" maxlength="100">
<!-- Rangos de números -->
<input type="number" name="cantidad" min="1" max="10">
<!-- Rangos de fechas -->
<input type="date" name="fecha-inicio" min="2025-01-01" max="2025-12-31">
Aquí tienes un formulario de contacto completo que demuestra todos los conceptos que hemos cubierto:
<form action="/contacto" method="POST" novalidate>
<fieldset>
<legend>Información de Contacto</legend>
<div class="form-row">
<div class="form-group">
<label for="nombre">Nombre *</label>
<input type="text" id="nombre" name="nombre"
required minlength="2" maxlength="50">
</div>
<div class="form-group">
<label for="apellido">Apellido *</label>
<input type="text" id="apellido" name="apellido"
required minlength="2" maxlength="50">
</div>
</div>
<div class="form-group">
<label for="email">Dirección de Email *</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="telefono">Número de Teléfono</label>
<input type="tel" id="telefono" name="telefono"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{3}"
placeholder="123-456-789">
</div>
</fieldset>
<fieldset>
<legend>Detalles del Mensaje</legend>
<div class="form-group">
<label for="asunto">Asunto *</label>
<select id="asunto" name="asunto" required>
<option value="">Elige un asunto</option>
<option value="general">Consulta General</option>
<option value="soporte">Soporte Técnico</option>
<option value="facturacion">Pregunta de Facturación</option>
</select>
</div>
<div class="form-group">
<label for="mensaje">Mensaje *</label>
<textarea id="mensaje" name="mensaje" required
minlength="10" maxlength="1000" rows="5"
placeholder="Por favor describe tu consulta..."></textarea>
</div>
<div class="form-group">
<label for="prioridad">Nivel de Prioridad</label>
<input type="range" id="prioridad" name="prioridad"
min="1" max="5" value="3">
<output for="prioridad">3</output>
</div>
</fieldset>
<fieldset>
<legend>Preferencias</legend>
<div class="form-group">
<label>
<input type="checkbox" name="newsletter" value="si">
Suscribirse a nuestro boletín
</label>
</div>
<div class="form-group">
<fieldset>
<legend>Método de Contacto Preferido</legend>
<label>
<input type="radio" name="metodo-contacto" value="email" checked>
Email
</label>
<label>
<input type="radio" name="metodo-contacto" value="telefono">
Teléfono
</label>
</fieldset>
</div>
</fieldset>
<div class="form-actions">
<button type="reset">Limpiar Formulario</button>
<button type="submit">Enviar Mensaje</button>
</div>
</form>
Aunque esta guía se enfoca en HTML, aquí tienes algunos consejos de CSS para mejor presentación de formularios:
/* Estilizado básico de formularios */
.form-group {
margin-bottom: 1rem;
}
.form-row {
display: flex;
gap: 1rem;
}
label {
display: block;
margin-bottom: 0.25rem;
font-weight: 500;
}
input, select, textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
button {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
button[type="submit"] {
background-color: #007bff;
color: white;
}
<fieldset>
y <legend>
<fieldset>
<legend>Información de Facturación</legend>
<div class="form-group">
<label for="tarjeta">Número de Tarjeta</label>
<input type="text" id="tarjeta" name="tarjeta"
pattern="[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}"
placeholder="1234-5678-9012-3456">
</div>
<div class="form-row">
<div class="form-group">
<label for="expiracion">Fecha de Expiración</label>
<input type="month" id="expiracion" name="expiracion">
</div>
<div class="form-group">
<label for="cvv">CVV</label>
<input type="text" id="cvv" name="cvv"
pattern="[0-9]{3,4}" maxlength="4">
</div>
</div>
</fieldset>
<datalist>
para Autocompletado<label for="navegador">Elige tu navegador:</label>
<input list="navegadores" id="navegador" name="navegador">
<datalist id="navegadores">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
<option value="Opera">
</datalist>
<output>
para Mostrar Resultados<form oninput="resultado.value=parseInt(a.value)+parseInt(b.value)">
<label for="a">Primer número:</label>
<input type="number" id="a" name="a" value="0">
<label for="b">Segundo número:</label>
<input type="number" id="b" name="b" value="0">
<label for="resultado">Resultado:</label>
<output name="resultado" for="a b">0</output>
</form>
Aunque HTML5 proporciona validación básica, a veces necesitas validación más compleja:
<form id="formulario-registro">
<div class="form-group">
<label for="contraseña">Contraseña</label>
<input type="password" id="contraseña" name="contraseña" required>
</div>
<div class="form-group">
<label for="confirmar-contraseña">Confirmar Contraseña</label>
<input type="password" id="confirmar-contraseña" name="confirmarContraseña" required>
<div class="error-message" id="error-contraseña"></div>
</div>
<button type="submit">Registrarse</button>
</form>
<script>
document.getElementById('formulario-registro').addEventListener('submit', function(e) {
const contraseña = document.getElementById('contraseña').value;
const confirmar = document.getElementById('confirmar-contraseña').value;
const errorDiv = document.getElementById('error-contraseña');
if (contraseña !== confirmar) {
e.preventDefault();
errorDiv.textContent = 'Las contraseñas no coinciden';
errorDiv.style.color = 'red';
} else {
errorDiv.textContent = '';
}
});
</script>
Asegúrate de que tus formularios funcionen bien en todos los dispositivos:
/* Diseño responsivo para formularios */
.form-container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
input, select, textarea, button {
font-size: 16px; /* Previene zoom en iOS */
}
button {
width: 100%;
padding: 12px;
}
}
<form action="/enviar" method="POST">
<!-- Token CSRF para seguridad -->
<input type="hidden" name="_token" value="abc123xyz789">
<!-- Resto del formulario -->
<input type="text" name="nombre" required>
<button type="submit">Enviar</button>
</form>
<!-- Siempre valida y sanitiza en el servidor -->
<form action="/comentario" method="POST">
<label for="comentario">Comentario:</label>
<textarea id="comentario" name="comentario"
maxlength="500" required></textarea>
<button type="submit">Publicar Comentario</button>
</form>
Para formularios largos, considera dividirlos en pasos:
<form id="formulario-multipaso">
<!-- Paso 1: Información Personal -->
<fieldset class="paso" id="paso-1">
<legend>Paso 1: Información Personal</legend>
<div class="form-group">
<label for="nombre-completo">Nombre Completo</label>
<input type="text" id="nombre-completo" name="nombreCompleto" required>
</div>
<button type="button" onclick="siguientePaso(2)">Siguiente</button>
</fieldset>
<!-- Paso 2: Información de Contacto -->
<fieldset class="paso" id="paso-2" style="display: none;">
<legend>Paso 2: Información de Contacto</legend>
<div class="form-group">
<label for="email-paso2">Email</label>
<input type="email" id="email-paso2" name="email" required>
</div>
<button type="button" onclick="pasoAnterior(1)">Anterior</button>
<button type="button" onclick="siguientePaso(3)">Siguiente</button>
</fieldset>
<!-- Paso 3: Confirmación -->
<fieldset class="paso" id="paso-3" style="display: none;">
<legend>Paso 3: Confirmación</legend>
<div id="resumen"></div>
<button type="button" onclick="pasoAnterior(2)">Anterior</button>
<button type="submit">Enviar</button>
</fieldset>
</form>
Los formularios HTML son esenciales para crear experiencias web interactivas. Al entender el elemento <form>
, varios tipos de input, etiquetado apropiado y validación básica, puedes crear formularios que sean tanto funcionales como accesibles.
Recuerda estos principios clave:
Con estos fundamentos en su lugar, podrás crear formularios que proporcionen excelentes experiencias de usuario mientras recopilan los datos que tu aplicación necesita.
Continúa leyendo con estos artículos relacionados
Domina las imágenes HTML con esta guía completa que cubre el tag img, texto alternativo, formatos de archivo, imágenes responsivas, srcset y optimización de rendimiento web.
Aprende a crear y estilizar listas en HTML con elementos ul, ol y dl. Guía completa sobre listas anidadas, accesibilidad y mejores prácticas de CSS.
Aprende a crear tablas HTML desde lo básico hasta técnicas avanzadas. Domina los elementos table, tr, td, th, accesibilidad, diseño responsivo y cuándo usar tablas apropiadamente.
Descubre el poder de los elementos HTML semánticos como header, footer, article y section. Aprende cómo el marcado semántico mejora el SEO, la accesibilidad y la mantenibilidad del código.