Formularios
Los formularios son el principal mecanismo de interacción entre el usuario y una web: login, registro, búsqueda, checkout, contacto… Todos son formularios. Hacerlos bien desde el HTML marca la diferencia en accesibilidad y UX.
Estructura básica de un formulario
<form action="/enviar" method="POST">
<label for="nombre">Nombre completo</label>
<input type="text" id="nombre" name="nombre" />
<button type="submit">Enviar</button>
</form>
action→ URL a donde se envían los datosmethod→GET(datos en la URL) oPOST(datos en el cuerpo)name→ nombre del campo que llega al servidor
La etiqueta <label>
El <label> no es opcional — es fundamental para la accesibilidad. Asocia un texto descriptivo a su campo:
<!-- ✅ Asociado con 'for' + 'id' -->
<label for="email">Correo electrónico</label>
<input type="email" id="email" name="email" />
<!-- ✅ Envolviendo el input (también válido) -->
<label>
Correo electrónico
<input type="email" name="email" />
</label>
Con <label> correctamente asociado, al clicar el texto también se activa el campo — mejor UX y accesibilidad para lectores de pantalla.
Tipos de <input>
El atributo type cambia completamente el comportamiento:
<input type="text" name="nombre" placeholder="Tu nombre" />
<input type="email" name="email" placeholder="tu@email.com" />
<input type="password" name="password" placeholder="Contraseña" />
<input type="number" name="edad" min="0" max="120" />
<input type="tel" name="telefono" placeholder="+34 600 000 000" />
<input type="url" name="web" placeholder="https://" />
<input type="date" name="fecha" />
<input type="time" name="hora" />
<input type="color" name="color" />
<input type="range" name="volumen" min="0" max="100" step="5" />
<input type="file" name="archivo" accept=".pdf,.jpg" />
<input type="hidden" name="token" value="abc123" />
<input type="checkbox" name="acepto" id="acepto" />
<input type="radio" name="sexo" value="m" id="masculino" />
<input type="search" name="q" placeholder="Buscar..." />
El navegador adapta el teclado en móvil según el type (numérico para number, @ para email, etc.).
<textarea>
Para texto de varias líneas:
<label for="mensaje">Mensaje</label>
<textarea id="mensaje" name="mensaje" rows="5" cols="40" placeholder="Escribe aquí..."></textarea>
<select> y <option>
Desplegables de selección:
<label for="pais">País</label>
<select id="pais" name="pais">
<option value="">Selecciona un país</option>
<option value="es">España</option>
<option value="mx">México</option>
<option value="ar">Argentina</option>
</select>
<!-- Agrupación con optgroup -->
<select name="lenguaje">
<optgroup label="Frontend">
<option value="html">HTML</option>
<option value="css">CSS</option>
</optgroup>
<optgroup label="Backend">
<option value="node">Node.js</option>
<option value="python">Python</option>
</optgroup>
</select>
Validación nativa del navegador
HTML incluye validación sin JavaScript:
<form>
<!-- required: campo obligatorio -->
<input type="text" name="nombre" required />
<!-- minlength / maxlength: longitud mínima y máxima -->
<input type="text" name="usuario" minlength="3" maxlength="20" required />
<!-- min / max para números y fechas -->
<input type="number" name="edad" min="18" max="99" required />
<!-- pattern: validación con regex -->
<input
type="text"
name="codigo-postal"
pattern="[0-9]{5}"
title="Introduce 5 dígitos"
required
/>
<button type="submit">Enviar</button>
</form>
Fieldset y legend
Para agrupar campos relacionados:
<form>
<fieldset>
<legend>Datos personales</legend>
<label for="nombre">Nombre</label>
<input type="text" id="nombre" name="nombre" />
<label for="apellido">Apellido</label>
<input type="text" id="apellido" name="apellido" />
</fieldset>
<fieldset>
<legend>Preferencias</legend>
<label><input type="checkbox" name="newsletter" /> Recibir newsletter</label>
<label><input type="checkbox" name="ofertas" /> Recibir ofertas</label>
</fieldset>
<button type="submit">Guardar</button>
</form>
En la última lección del curso vemos HTML5 semántico: las etiquetas que dan significado real a la estructura de la página.