En clase aprendí a estructurar páginas web viendo primero un dibujo de cómo se organiza una página con header, nav, main, article… y desde entonces siempre he montado mis HTML así, en vez de a base de div. Entiendo que con div también se puede hacer todo, pero cuando tienes quince div anidados sin ningún elemento semántico de por medio, es fácil perderte y no saber en qué parte de la estructura estás escribiendo.
El mismo esquema, dos formas de escribirlo
Antes de HTML5, una página se estructuraba así, con div identificados por id o class para darles significado:
<body>
<div id="cabecera"> … </div>
<div id="barra_navegacion"> … </div>
<div id="seccion">
<div class="articulo"> … </div>
<div class="articulo"> … </div>
</div>
<div id="pie"> … </div>
</body>
Con elementos semánticos de HTML5, exactamente la misma estructura queda así:
<body>
<header> … </header>
<nav> … </nav>
<main>
<section id="seccion">
<article> … </article>
<article> … </article>
<aside> … </aside>
</section>
</main>
<footer> … </footer>
</body>
Visualmente ocupan lo mismo y en el navegador, sin CSS, se comportan igual. La diferencia no es de aspecto — es que un div no dice nada sobre lo que contiene, mientras que header, nav o article explican su función solo con el nombre, tanto para ti leyendo el código seis meses después como para un lector de pantalla o un buscador que intenta entender la estructura de la página.
Cada etiqueta tiene sus propias reglas, y no son iguales entre sí
Esto es algo que en clase se pasa rápido pero que conviene tener claro, porque no todos los elementos semánticos se comportan igual:
<header>: agrupa el título, el menú o el logo de una página, sección o artículo. Una página puede tener variosheader(uno general, otro dentro de unarticle), pero nunca se debe colocar unheaderdentro de otroheader, ni dentro de unfooter.<footer>: la misma lógica queheaderpero al revés — agrupa autor, copyright, términos de uso. También puede haber varios en una página, y tampoco puede anidarse dentro de otrofooterni dentro de unheader.<main>: al contrario que los anteriores, solo puede aparecer una vez por página. Marca el contenido principal, diferenciándolo del contenido secundario como menús o publicidad.<section>: divide la página en partes o secciones, y sí se puede anidar para crear subsecciones dentro de otras secciones. Puede haber tantos como haga falta.<nav>: agrupa un bloque de enlaces, típicamente un menú de navegación. También puede haber varios (por ejemplo, un menú principal y otro en el pie).<article>: para contenido que tiene significado por sí mismo, incluso si lo sacas de la página — un post de un foro, una noticia, un comentario de usuario. Puede contener dentroheader,section,asideyfooterpropios.<aside>: contenido extra, complementario, del que se podría prescindir — una columna lateral con banners, o información relacionada dentro de unarticle.
Un ejemplo completo
Así se vería una página real usando todo lo anterior, con la estructura que solemos usar de base en clase:
<!DOCTYPE html>
<html lang="es-ES">
<head>
<meta charset="UTF-8">
<title>Historia de HTML</title>
</head>
<body>
<header>
<h1>Historia de HTML</h1>
<p>Desde 1989 hasta nuestros días</p>
</header>
<section id="inicio">
<h2>Inicios en HTML. Tim Berners Lee</h2>
<p>...</p>
</section>
<section id="versiones">
<h2>De HTML 4 a HTML 5 pasando por XHTML</h2>
<p>...</p>
</section>
<footer>
<p>Realizado por Antonio Moreno</p>
</footer>
</body>
</html>
Dos etiquetas semánticas menos conocidas: hgroup y figure
Además de las siete etiquetas principales de estructura, HTML5 incluye dos más pensadas para casos concretos que también merece la pena conocer:
<hgroup>: agrupa varios títulos (h1ah6) que forman una unidad, como un título y su subtítulo, para poder darles un estilo común sin que cuenten como dos niveles de título independientes.
<article>
<hgroup>
<h2>El Principito</h2>
<h3>Infantil</h3>
</hgroup>
</article>
<figure>y<figcaption>:figureagrupa una imagen junto con todo lo que la acompaña (pie de foto, párrafos relacionados), yfigcaptionmarca específicamente el pie de esa imagen.
<figure>
<img src="Alhambra.jpg" alt="Vista de La Alhambra" width="350" height="400">
<figcaption>
Vista de La Alhambra desde el Mirador de San Nicolás
</figcaption>
</figure>
La ventaja de usar figure/figcaption en vez de un simple div con un img y un p suelto es la misma que con el resto de elementos semánticos: cualquier herramienta (lector de pantalla, buscador) entiende automáticamente que ese párrafo es específicamente el pie de esa imagen concreta, sin necesidad de adivinarlo por la posición en el código.
Inline vs block: por qué esto también importa aquí
Los elementos semánticos que hemos visto (header, nav, main, section, article, aside, footer) son todos elementos de bloque: ocupan todo el ancho de su contenedor por defecto y fuerzan un salto antes y después. Esto los distingue de los elementos en línea como span, strong o em, que solo ocupan el espacio justo de su contenido y pueden convivir dentro de una misma línea de texto. Tiene sentido: no usarías un <header> en mitad de una frase, igual que no montarías la estructura general de una página con <span>.
Pon a prueba lo que has entendido
¿Cuál de estos elementos semánticos NO puede aparecer más de una vez en la misma página?
Resumen rápido
Los elementos semánticos de HTML5 (header, nav, main, section, article, aside, footer) estructuran una página igual que lo haría un div con id, pero explicando su función con el propio nombre de la etiqueta. Cada uno tiene reglas distintas — main solo puede aparecer una vez, header y footer no se pueden anidar entre sí, section sí se puede anidar. Dentro de esa estructura semántica siguen existiendo casos donde div y span tienen su sitio, para agrupaciones sin significado propio — la diferencia entre ambos la tienes en div vs span en HTML, con ejemplos de cuándo usar cada uno.