HTML lo fuimos viendo en clase con actividades progresivas: primero etiquetas sueltas, luego estructura de página completa, hasta llegar a un examen final donde tocaba montar una página sencilla usando todo lo dado en los ejercicios anteriores. De todo el temario, lo que de verdad cuesta al principio no es la teoría general — es cuando llegas a tablas y formularios, que tienen más partes moviéndose a la vez que el resto de etiquetas.

Qué es HTML, en una frase

HTML (HyperText Markup Language) no es un lenguaje de programación — es un lenguaje de marcado: no calcula ni decide nada, solo describe la estructura y el contenido de una página (qué es un título, qué es un párrafo, qué es una imagen), dejando que sea CSS quien decida cómo se ve todo eso.

Esta distinción importa más de lo que parece al empezar: en HTML no hay variables, ni condiciones, ni bucles. Si vienes esperando “programar”, el cambio de mentalidad es justo ese — aquí describes, no ordenas.

La estructura básica que se repite siempre

Toda página HTML parte del mismo esqueleto, y una vez lo interiorizas, ya no se te olvida:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Título de la página</title>
  </head>
  <body>
    <h1>Contenido visible aquí</h1>
  </body>
</html>
PartePara qué sirve
<!DOCTYPE html>Le dice al navegador que use el estándar HTML5
<html lang="es">Contenedor de toda la página; lang indica el idioma (importante para buscadores y lectores de pantalla)
<head>Información sobre la página, no visible en pantalla
<meta charset="UTF-8">Codificación de caracteres: sin esto, las tildes y las ñ se ven mal
<title>El texto que aparece en la pestaña del navegador
<body>Todo lo que sí se ve en la página

Etiquetas más comunes, de un vistazo

EtiquetaPara qué sirve
<h1> a <h6>Títulos y subtítulos, de mayor a menor importancia
<p>Párrafo de texto
<a href="...">Enlace a otra página o sección
<img src="..." alt="...">Imagen (el alt describe la imagen si no carga)
<ul> / <ol> / <li>Lista sin orden / lista numerada / cada elemento de la lista
<div>Contenedor genérico, sin significado propio, para agrupar y dar estilo con CSS
<span>Como div, pero para trozos pequeños dentro de una línea de texto

Elementos de bloque vs elementos en línea

Otra distinción que ayuda a entender por qué las cosas se colocan como se colocan:

  • De bloque (div, p, h1, ul): ocupan todo el ancho disponible y empiezan en una línea nueva.
  • En línea (span, a, img): ocupan solo lo que necesitan y se colocan seguidos, dentro de la misma línea.

Por qué las tablas cuestan más de lo que parece

Una tabla en HTML no es una sola etiqueta, es una jerarquía de varias etiquetas anidadas, y ahí es donde la mayoría se pierde al principio:

<table>
  <thead>
    <tr>
      <th>Alumno</th>
      <th>Nota</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Antonio</td>
      <td>8</td>
    </tr>
    <tr>
      <td>Lucía</td>
      <td>9</td>
    </tr>
  </tbody>
</table>
EtiquetaSignificadoQué contiene
<table>La tabla completaTodo lo demás
<thead>Cabecera de la tablaFilas de cabecera
<tbody>Cuerpo de la tablaFilas de datos
<tr>Table Row — una filaCeldas
<th>Table Header — celda de cabeceraTexto (aparece en negrita y centrado por defecto)
<td>Table Data — celda normalTexto o contenido

La dificultad no está en ninguna etiqueta por separado, sino en no perder la cuenta de en qué nivel de anidación estás cuando la tabla crece. Un truco que ayuda mucho al principio: escribir primero la estructura vacía completa (table → thead → tr → th, y luego tbody → tr → td) y solo después rellenar el contenido. Así nunca cierras una etiqueta en el sitio equivocado.

Combinar celdas: colspan y rowspan

Cuando una celda tiene que ocupar varias columnas o varias filas:

<tr>
  <td colspan="2">Ocupa dos columnas</td>
</tr>
<tr>
  <td rowspan="2">Ocupa dos filas</td>
  <td>Celda normal</td>
</tr>

Por qué los formularios cuestan todavía más

Los formularios añaden una capa extra: no solo hay que estructurar el contenido, sino declarar qué tipo de dato espera cada campo y cómo se va a enviar:

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

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

  <label for="mensaje">Mensaje:</label>
  <textarea id="mensaje" name="mensaje" rows="4"></textarea>

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

Los tres atributos que más se confunden

AtributoPara qué sirveQuién lo usa
idIdentificar el campo dentro de la páginaEl <label> y el CSS/JavaScript
nameNombre con el que se envía el dato al servidorEl servidor que recibe el formulario
for (en <label>)Vincular la etiqueta con su campoEl navegador y los lectores de pantalla

Lo que suele confundir aquí es la relación entre <label for="..."> y el id del <input>: tienen que coincidir exactamente. Si no coinciden, la página sigue funcionando visualmente, pero pierdes accesibilidad (un lector de pantalla no sabrá qué etiqueta corresponde a qué campo) y el usuario ya no puede hacer clic en el texto de la etiqueta para enfocar el campo.

Y ojo con otra confusión típica: el name es el que viaja al servidor, no el id. Si te olvidas del name, el campo simplemente no se envía, aunque el usuario lo haya rellenado.

Tipos de input más habituales

typeQué hace
textCampo de texto libre
emailTexto, pero el navegador valida que tenga formato de email
passwordOculta lo que se escribe
numberSolo admite números, con flechas de incremento
checkboxCasilla de verificación (varias opciones a la vez)
radioBotón de opción (solo una del grupo)
dateSelector de fecha
submitBotón que envía el formulario

Cada type se comporta de forma distinta, y merece la pena probarlos uno a uno en un archivo de prueba para interiorizar las diferencias — sobre todo checkbox vs radio, que se confunden mucho al principio: los radio del mismo grupo deben compartir el mismo name para que solo se pueda elegir uno.

Pon a prueba lo que has entendido

En un formulario, el atributo 'for' de un <label> no coincide con el 'id' del <input>. ¿Qué ocurre?

Resumen rápido

  • HTML describe estructura y contenido, no apariencia — eso es trabajo de CSS. No es un lenguaje de programación.
  • Toda página parte del mismo esqueleto: <!DOCTYPE html>, <head> (información no visible) y <body> (contenido visible).
  • Las tablas cuestan por la jerarquía anidada (tablethead/tbodytrth/td), no por la dificultad de cada etiqueta suelta. Escribir la estructura vacía primero ayuda mucho.
  • En formularios: id vincula con el <label>, name es lo que se envía al servidor. Confundirlos es el error más común al empezar.