Formularios y tablas

Inscribirse en un taller, pedir presupuesto, buscar en un catálogo: los formularios son la parte de la web donde el usuario habla.

Formulario = <form> + campos con su <label> + <button type="submit">.

El type adecuado da teclado y validación gratis; required, min, max… validan.

Agrupa opciones con <fieldset> y <legend>.

Tablas solo para datos, con <caption>, <th> y scope.

  • Inscribirse en un taller, pedir presupuesto, buscar en un catálogo: los formularios son la parte de la web donde el usuario habla. Y las tablas sirven para lo contrario: presentar datos ordenados para que se lean de un vistazo. Las dos cosas se diseñan mucho y se construyen mal a menudo. Aquí verás cómo hacerlo bien.
  • <form action="#" method="post"> <label for="nombre">Nombre</label> <input type="text" id="nombre" name="nombre" autocomplete="name" required> <label for="correo">Correo electrónico</label> <input type="email" id="correo" name="correo" autocomplete="email" required> <button type="submit">Inscribirme</button> </form>
  • PiezaPara qué sirve <form>Agrupa los campos. action indica adónde se envían los datos (en este curso no los enviaremos a ningún sitio: action="#"). <label>El texto que dice qué es cada campo. Su for debe coincidir con el id del campo. <input>Un campo. El atributo type cambia su comportamiento. nameEl nombre con el que viaja el dato al servidor. <button type="submit">Envía el formulario.
  • ⚠️ Atención. Todo campo necesita su <label>. Un texto de ejemplo dentro del campo (placeholder) no es una etiqueta: desaparece al escribir, suele tener poco contraste y muchos lectores de pantalla no lo anuncian. Además, pulsar sobre una etiqueta bien asociada pone el cursor en su campo: el área de clic es más grande.
  • El type correcto mejora la experiencia sin escribir ni una línea de JavaScript: en el móvil aparece el teclado adecuado y el navegador valida el formato.

Introducción

Inscribirse en un taller, pedir presupuesto, buscar en un catálogo: los formularios son la parte de la web donde el usuario habla. Y las tablas sirven para lo contrario: presentar datos ordenados para que se lean de un vistazo. Las dos cosas se diseñan mucho y se construyen mal a menudo. Aquí verás cómo hacerlo bien.

Anatomía de un formulario

<form action="#" method="post"> <label for="nombre">Nombre</label> <input type="text" id="nombre" name="nombre" autocomplete="name" required> <label for="correo">Correo electrónico</label> <input type="email" id="correo" name="correo" autocomplete="email" required> <button type="submit">Inscribirme</button> </form>

PiezaPara qué sirve <form>Agrupa los campos. action indica adónde se envían los datos (en este curso no los enviaremos a ningún sitio: action="#"). <label>El texto que dice qué es cada campo. Su for debe coincidir con el id del campo. <input>Un campo. El atributo type cambia su comportamiento. nameEl nombre con el que viaja el dato al servidor. <button type="submit">Envía el formulario.

⚠️ Atención. Todo campo necesita su <label>. Un texto de ejemplo dentro del campo (placeholder) no es una etiqueta: desaparece al escribir, suele tener poco contraste y muchos lectores de pantalla no lo anuncian. Además, pulsar sobre una etiqueta bien asociada pone el cursor en su campo: el área de clic es más grande.

Tipos de campo

El type correcto mejora la experiencia sin escribir ni una línea de JavaScript: en el móvil aparece el teclado adecuado y el navegador valida el formato.

typeUsoEn el móvil textTexto cortoTeclado normal emailCorreoTeclado con @ telTeléfonoTeclado numérico numberNúmeros (con min, max, step)Teclado numérico dateFechasSelector de fecha urlDirecciones webTeclado con / y .com checkboxCasillas (varias opciones)— radioUna opción entre varias (mismo name)—

Otros elementos: <textarea> para textos largos y <select> con <option> para listas desplegables.

Agrupar opciones

Cuando varias casillas o botones de opción responden a la misma pregunta, se agrupan con <fieldset> y la pregunta va en <legend>:

Validación nativa

El navegador puede comprobar datos antes de enviar:

required: el campo es obligatorio. minlength / maxlength: longitud de texto. min / max: valores numéricos o fechas. pattern: una expresión regular (avanzado).

Y CSS puede reaccionar al estado del campo con las pseudoclases :invalid, :valid, :focus y :focus-visible:

input:focus-visible { outline: 3px solid #fcbf49; outline-offset: 2px; } input:user-invalid { border-color: #b3261e; /* solo tras interactuar con el campo */ }

Tablas: para datos, no para maquetar

Una tabla es para datos tabulares: horarios, precios, comparativas. Hace años se usaban para maquetar páginas enteras; hoy eso es un error (para maquetar están Flexbox y Grid, en las siguientes páginas).

<table> <caption>Horario de los talleres</caption> <thead> <tr> <th scope="col">Taller</th> <th scope="col">Día</th> <th scope="col">Plazas</th> </tr> </thead> <tbody> <tr> <th scope="row">Risografía</th> <td>Lunes</td> <td>12</td> </tr> </tbody> </table>

<caption>: título de la tabla (lo anuncian los lectores de pantalla). <thead> / <tbody>: cabecera y cuerpo. <tr>: fila; <th>: celda de encabezado; <td>: celda de datos. scope="col" o scope="row": indica si el encabezado es de columna o de fila.

Para darles estilo: border-collapse: collapse une los bordes, padding en las celdas da aire y font-variant-numeric: tabular-nums alinea las cifras.

Errores frecuentes

Campos sin <label> o con for que no coincide con el id. Usar placeholder como única etiqueta. Botones hechos con <div>: no se pueden usar con teclado. Usa <button>. Tablas sin encabezados <th> o usadas para maquetar.

HTML
28

Formularios y tablas

Inscribirse en un taller, pedir presupuesto, buscar en un catálogo: los formularios son la parte de la web donde el usuario habla.

Código del tema: <form>

📘 Teoría

Introducción

Inscribirse en un taller, pedir presupuesto, buscar en un catálogo: los formularios son la parte de la web donde el usuario habla. Y las tablas sirven para lo contrario: presentar datos ordenados para que se lean de un vistazo. Las dos cosas se diseñan mucho y se construyen mal a menudo. Aquí verás cómo hacerlo bien.

Anatomía de un formulario

<form action="#" method="post">
  <label for="nombre">Nombre</label>
  <input type="text" id="nombre" name="nombre" autocomplete="name" required>

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

  <button type="submit">Inscribirme</button>
</form>
PiezaPara qué sirve
<form>Agrupa los campos. action indica adónde se envían los datos (en este curso no los enviaremos a ningún sitio: action="#").
<label>El texto que dice qué es cada campo. Su for debe coincidir con el id del campo.
<input>Un campo. El atributo type cambia su comportamiento.
nameEl nombre con el que viaja el dato al servidor.
<button type="submit">Envía el formulario.

⚠️ Atención. Todo campo necesita su <label>. Un texto de ejemplo dentro del campo (placeholder) no es una etiqueta: desaparece al escribir, suele tener poco contraste y muchos lectores de pantalla no lo anuncian. Además, pulsar sobre una etiqueta bien asociada pone el cursor en su campo: el área de clic es más grande.

Tipos de campo

El type correcto mejora la experiencia sin escribir ni una línea de JavaScript: en el móvil aparece el teclado adecuado y el navegador valida el formato.

typeUsoEn el móvil
textTexto cortoTeclado normal
emailCorreoTeclado con @
telTeléfonoTeclado numérico
numberNúmeros (con min, max, step)Teclado numérico
dateFechasSelector de fecha
urlDirecciones webTeclado con / y .com
checkboxCasillas (varias opciones)—
radioUna opción entre varias (mismo name)—

Otros elementos: <textarea> para textos largos y <select> con <option> para listas desplegables.

Agrupar opciones

Cuando varias casillas o botones de opción responden a la misma pregunta, se agrupan con <fieldset> y la pregunta va en <legend>:

Validación nativa

El navegador puede comprobar datos antes de enviar:

  • required: el campo es obligatorio.
  • minlength / maxlength: longitud de texto.
  • min / max: valores numéricos o fechas.
  • pattern: una expresión regular (avanzado).

Y CSS puede reaccionar al estado del campo con las pseudoclases :invalid, :valid, :focus y :focus-visible:

input:focus-visible {
  outline: 3px solid #fcbf49;
  outline-offset: 2px;
}
input:user-invalid {
  border-color: #b3261e;   /* solo tras interactuar con el campo */
}

💡 Consejo. Nunca quites el contorno de foco (outline: none) sin poner otro indicador visible. Quien navega con teclado necesita saber dónde está.

Tablas: para datos, no para maquetar

Una tabla es para datos tabulares: horarios, precios, comparativas. Hace años se usaban para maquetar páginas enteras; hoy eso es un error (para maquetar están Flexbox y Grid, en las siguientes páginas).

<table>
  <caption>Horario de los talleres</caption>
  <thead>
    <tr>
      <th scope="col">Taller</th>
      <th scope="col">Día</th>
      <th scope="col">Plazas</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Risografía</th>
      <td>Lunes</td>
      <td>12</td>
    </tr>
  </tbody>
</table>
  • <caption>: título de la tabla (lo anuncian los lectores de pantalla).
  • <thead> / <tbody>: cabecera y cuerpo.
  • <tr>: fila; <th>: celda de encabezado; <td>: celda de datos.
  • scope="col" o scope="row": indica si el encabezado es de columna o de fila.

Para darles estilo: border-collapse: collapse une los bordes, padding en las celdas da aire y font-variant-numeric: tabular-nums alinea las cifras.

Errores frecuentes

  • Campos sin <label> o con for que no coincide con el id.
  • Usar placeholder como única etiqueta.
  • Botones hechos con <div>: no se pueden usar con teclado. Usa <button>.
  • Tablas sin encabezados <th> o usadas para maquetar.

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros. culTest

La hice en febrero de 2026 para facilitar el aprendizaje de mis alumnos. La idea es aprender desarrollo web practicando y que el proyecto siga creciendo con nuevos temas, tests y retos.

Está inspirada en MDN, W3Schools, CodePen, Manz y muchos otros sitios de documentación sobre desarrollo web. Quería combinar teoría útil, ejemplos ejecutables, retos y el sistema de tests que ya tenía en culTest. culTest

Si te gustó, si no te gustó o si quieres escribirme, puedes hacerlo en cristianeslava@gmail.com