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>
| Parte | Para 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
| Etiqueta | Para 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>
| Etiqueta | Significado | Qué contiene |
|---|---|---|
<table> | La tabla completa | Todo lo demás |
<thead> | Cabecera de la tabla | Filas de cabecera |
<tbody> | Cuerpo de la tabla | Filas de datos |
<tr> | Table Row — una fila | Celdas |
<th> | Table Header — celda de cabecera | Texto (aparece en negrita y centrado por defecto) |
<td> | Table Data — celda normal | Texto 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
| Atributo | Para qué sirve | Quién lo usa |
|---|---|---|
id | Identificar el campo dentro de la página | El <label> y el CSS/JavaScript |
name | Nombre con el que se envía el dato al servidor | El servidor que recibe el formulario |
for (en <label>) | Vincular la etiqueta con su campo | El 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
type | Qué hace |
|---|---|
text | Campo de texto libre |
email | Texto, pero el navegador valida que tenga formato de email |
password | Oculta lo que se escribe |
number | Solo admite números, con flechas de incremento |
checkbox | Casilla de verificación (varias opciones a la vez) |
radio | Botón de opción (solo una del grupo) |
date | Selector de fecha |
submit | Botó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 (
table→thead/tbody→tr→th/td), no por la dificultad de cada etiqueta suelta. Escribir la estructura vacía primero ayuda mucho. - En formularios:
idvincula con el<label>,namees lo que se envía al servidor. Confundirlos es el error más común al empezar.