Semántica y Accesibilidad
Aprendé a escribir HTML con significado real. El HTML semántico mejora el SEO, la accesibilidad y hace tu código más fácil de mantener.
¿Qué es HTML semántico?
HTML semántico significa usar la etiqueta correcta para cada tipo de contenido. No es solo que la página se vea bien — es que tenga significado. Los buscadores, los lectores de pantalla y otros desarrolladores entienden mejor un HTML bien estructurado.
Sin semántica vs con semántica
<!-- ❌ Sin semántica — todo son divs, sin significado -->
<div class="header">
<div class="nav">...</div>
</div>
<div class="main">
<div class="article">...</div>
<div class="sidebar">...</div>
</div>
<div class="footer">...</div>
<!-- ✅ Con semántica — cada etiqueta describe su contenido -->
<header>
<nav>...</nav>
</header>
<main>
<article>...</article>
<aside>...</aside>
</main>
<footer>...</footer>
Google usa la estructura semántica para entender qué es el contenido principal de tu página (SEO). Los lectores de pantalla para ciegos usan <nav>, <main> y <aside> para navegar sin usar el mouse.
Etiquetas de sección
HTML5 introdujo etiquetas que describen el rol de cada parte de la página:
<header>
<!-- Encabezado de la página O de una sección.
Normalmente contiene el logo, título y navegación principal. -->
<h1>Mi Sitio Web</h1>
<nav>...</nav>
</header>
<nav>
<!-- Navegación principal del sitio.
Solo para bloques de enlaces de navegación importantes. -->
<ul>
<li><a href="/">Inicio</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
<main>
<!-- Contenido principal y único de la página.
Solo debe haber UN <main> por página. -->
<section>
<!-- Agrupa contenido temáticamente relacionado.
Siempre debería tener un encabezado (h2, h3...). -->
<h2>Últimos artículos</h2>
...
</section>
<article>
<!-- Contenido independiente y autocontenido:
un post, una noticia, un comentario, una tarjeta de producto.
Tendría sentido si lo sacaras de la página y lo leerías solo. -->
<h2>Título del artículo</h2>
<p>Contenido...</p>
</article>
<aside>
<!-- Contenido secundario, relacionado pero no esencial:
sidebar, publicidades, enlaces relacionados, bio del autor. -->
<h3>Artículos relacionados</h3>
...
</aside>
</main>
<footer>
<!-- Pie de la página O de una sección.
Copyright, links legales, contacto. -->
<p>© 2026 Mi Sitio</p>
</footer>
| Etiqueta | Qué representa | Cantidad por página |
|---|---|---|
<header> | Encabezado de página o sección | Varios (uno por sección) |
<nav> | Navegación principal | Generalmente 1-2 |
<main> | Contenido principal único | Solo 1 |
<section> | Sección temática con encabezado | Varios |
<article> | Contenido autocontenido | Varios |
<aside> | Contenido secundario / sidebar | Varios |
<footer> | Pie de página o sección | Varios (uno por sección) |
Etiquetas de texto con significado
Hay etiquetas que cambian el estilo visualmente, pero lo importante es que también comunican significado al navegador y a los lectores de pantalla.
<!-- strong — importancia real, no solo negrita visual -->
<p>Recordá: <strong>guardar cambios antes de salir</strong>.</p>
<!-- em — énfasis, no solo cursiva visual -->
<p>No quiero <em>cualquier</em> resultado, quiero el mejor.</p>
<!-- mark — texto resaltado / relevante en el contexto actual -->
<p>Resultado de búsqueda: "cómo hacer <mark>pizza</mark> casera"</p>
<!-- small — aclaraciones, letra chica, copyright -->
<p><small>Precios sin IVA. Sujeto a cambios sin previo aviso.</small></p>
<!-- del e ins — texto eliminado e insertado (control de versiones) -->
<p>Precio: <del>$1500</del> <ins>$990</ins></p>
<!-- abbr — abreviatura con expansión -->
<p>Usamos <abbr title="HyperText Markup Language">HTML</abbr> y
<abbr title="Cascading Style Sheets">CSS</abbr>.</p>
<!-- time — fecha y hora legible por máquinas -->
<p>Publicado el <time datetime="2026-03-15">15 de marzo de 2026</time>.</p>
<!-- blockquote y cite — citas -->
<blockquote cite="https://fuente.com">
<p>El diseño no es solo cómo se ve, sino cómo funciona.</p>
<footer>— <cite>Steve Jobs</cite></footer>
</blockquote>
<!-- code, pre, kbd — contenido técnico -->
<p>Usá <code>document.getElementById()</code> para seleccionar el elemento.</p>
<pre><code>
function hola() {
console.log("Hola mundo");
}
</code></pre>
<p>Presioná <kbd>Ctrl</kbd> + <kbd>S</kbd> para guardar.</p>
<b> y <i> son solo estilos visuales (negrita, cursiva) sin significado semántico. <strong> indica importancia real y <em> indica énfasis real. Usá los semánticos siempre que sea posible; <b> e <i> solo cuando es puro estilo visual.
Accesibilidad — HTML para todos
La accesibilidad web (a11y) garantiza que personas con discapacidades puedan usar tu sitio. Más del 15% de la población mundial tiene alguna discapacidad. Un buen HTML semántico es la base de la accesibilidad.
Jerarquía de encabezados correcta
<!-- ❌ Mal — saltan niveles, se usan por tamaño visual -->
<h1>Título de la página</h1>
<h4>Primera sección</h4> <!-- saltó h2 y h3 -->
<h2>Subsección</h2> <!-- baja a h2 sin sentido -->
<!-- ✅ Bien — jerarquía clara y lógica -->
<h1>Título de la página</h1>
<h2>Primera sección</h2>
<h3>Subsección A</h3>
<h3>Subsección B</h3>
<h2>Segunda sección</h2>
Atributos ARIA — Accessible Rich Internet Applications
Cuando el HTML nativo no alcanza, los atributos ARIA agregan información de accesibilidad:
<!-- aria-label — nombre accesible para elementos sin texto visible -->
<button aria-label="Cerrar ventana">✕</button>
<input type="search" aria-label="Buscar en el sitio">
<!-- aria-describedby — conecta un elemento con su descripción -->
<input type="password" id="pass" aria-describedby="requisitos">
<p id="requisitos">Mínimo 8 caracteres, una mayúscula y un número.</p>
<!-- aria-expanded — estado de un acordeón o menú -->
<button aria-expanded="false" aria-controls="menu">Menú</button>
<ul id="menu" hidden>...</ul>
<!-- aria-hidden — oculta elementos decorativos a lectores de pantalla -->
<span aria-hidden="true">★</span> 4.8 de 5 estrellas
<!-- role — define el rol cuando el HTML nativo no alcanza -->
<div role="alert">Error: el campo nombre es requerido.</div>
<div role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">75%</div>
<!-- aria-live — anuncia cambios dinámicos -->
<div aria-live="polite" id="estado"></div>
<!-- cuando JS cambia el contenido de #estado, el lector de pantalla lo anuncia -->
Antes de usar ARIA, intentá usar el elemento HTML nativo correcto. <button> es mejor que <div role="button"> porque ya trae el comportamiento de teclado y foco. ARIA complementa, no reemplaza.
Foco y navegación por teclado
Muchos usuarios navegan con el teclado (personas con movilidad reducida, usuarios avanzados). Todo elemento interactivo debe ser alcanzable con Tab.
<!-- tabindex="0" — hace que un elemento NO interactivo sea enfocable -->
<div tabindex="0" role="button">Acción personalizada</div>
<!-- tabindex="-1" — enfocable por JS pero no con Tab -->
<div id="modal" tabindex="-1">...</div>
<!-- útil para modales: el foco va al modal cuando se abre -->
<!-- tabindex="1+" — orden personalizado (evitarlo, confunde) -->
<!-- ❌ No hagas esto: rompe el flujo natural del documento -->
<input tabindex="3">
<input tabindex="1">
<input tabindex="2">
Saltar al contenido principal (skip link)
El primer enlace de la página debería permitir saltear la navegación. Es una técnica estándar para usuarios de teclado:
<!DOCTYPE html>
<html lang="es">
<head>...</head>
<body>
<!-- Primer elemento del body — invisible hasta que recibe foco -->
<a href="#contenido-principal" class="skip-link">
Saltar al contenido
</a>
<header>
<nav>...navegación larga...</nav>
</header>
<main id="contenido-principal">
<h1>Contenido de la página</h1>
</main>
</body>
</html>
<!-- El CSS para el skip link -->
<style>
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: white;
padding: 8px;
z-index: 100;
}
.skip-link:focus {
top: 0; /* aparece al recibir foco con Tab */
}
</style>
Meta tags y el <head> completo
El <head> contiene información sobre la página que no se muestra directamente
pero que es fundamental para el SEO, las redes sociales y la experiencia del usuario.
<head>
<!-- Codificación de caracteres — siempre lo primero -->
<meta charset="UTF-8">
<!-- Viewport — fundamental para responsive design -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Título de la página — aparece en la pestaña y en Google -->
<title>Título descriptivo de la página | Mi Sitio</title>
<!-- Descripción — aparece en los resultados de búsqueda -->
<meta name="description" content="Descripción clara en 150-160 caracteres
que resume el contenido de esta página.">
<!-- Open Graph — cómo se ve cuando se comparte en redes sociales -->
<meta property="og:title" content="Título para redes sociales">
<meta property="og:description" content="Descripción para redes sociales">
<meta property="og:image" content="https://misitio.com/imagen.jpg">
<meta property="og:url" content="https://misitio.com/esta-pagina">
<meta property="og:type" content="website">
<!-- Favicon -->
<link rel="icon" type="image/png" href="/favicon.png">
<!-- CSS externo -->
<link rel="stylesheet" href="/css/estilos.css">
<!-- Fuente de Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap"
rel="stylesheet">
<!-- Idioma canónico —evita contenido duplicado en SEO -->
<link rel="canonical" href="https://misitio.com/esta-pagina">
<!-- Tema de color para móviles -->
<meta name="theme-color" content="#264DE4">
</head>
El <title> es el texto azul que aparece en Google. La description es el texto gris debajo. Un buen title tiene entre 50-60 caracteres. Una buena description entre 150-160.
Datos estructurados — Schema.org
Los datos estructurados le dan a Google información extra sobre tu contenido para mostrar rich snippets en los resultados de búsqueda: estrellas de reseñas, precios de productos, eventos, recetas, etc.
Microdata
<!-- Producto con microdata -->
<div itemscope itemtype="https://schema.org/Product">
<h2 itemprop="name">Laptop ProMax 15"</h2>
<img itemprop="image" src="laptop.jpg" alt="Laptop ProMax">
<p itemprop="description">Laptop de alto rendimiento para profesionales.</p>
<div itemprop="offers" itemscope itemtype="https://schema.org/Offer">
<span itemprop="priceCurrency" content="ARS"></span>
Precio: <strong itemprop="price">$450.000</strong>
<link itemprop="availability" href="https://schema.org/InStock">En stock
</div>
</div>
JSON-LD (formato recomendado por Google)
<!-- Dentro del <head> o al final del <body> -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Cómo aprender HTML en 2026",
"datePublished": "2026-03-15",
"author": {
"@type": "Person",
"name": "Ana García"
},
"image": "https://misitio.com/imagen.jpg",
"description": "Guía completa para aprender HTML desde cero."
}
</script>
Google recomienda JSON-LD porque es más fácil de mantener — está separado del HTML y no mezclado con los atributos. Microdata es útil cuando querés que los datos estén directamente en el contenido visible.
Ejemplo Completo — Página de artículo
Una página de artículo de blog con semántica completa, accesibilidad y meta tags:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cómo aprender HTML — Mi Blog de Programación</title>
<meta name="description"
content="Guía completa para aprender HTML desde cero en 2026.">
<meta property="og:title" content="Cómo aprender HTML">
<meta property="og:image" content="https://misitio.com/og-html.jpg">
<link rel="canonical" href="https://misitio.com/aprender-html">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Cómo aprender HTML",
"author": { "@type": "Person", "name": "Ana García" },
"datePublished": "2026-03-15"
}
</script>
</head>
<body>
<a href="#contenido" class="skip-link">Saltar al contenido</a>
<header>
<a href="/">
<img src="logo.svg" alt="Mi Blog de Programación"
width="120" height="40">
</a>
<nav aria-label="Navegación principal">
<ul>
<li><a href="/">Inicio</a></li>
<li><a href="/blog" aria-current="page">Blog</a></li>
<li><a href="/contacto">Contacto</a></li>
</ul>
</nav>
</header>
<main id="contenido">
<article>
<header>
<h1>Cómo aprender HTML desde cero en 2026</h1>
<p>
Por <strong>Ana García</strong> —
<time datetime="2026-03-15">15 de marzo de 2026</time>
</p>
</header>
<figure>
<img src="html-cover.jpg"
alt="Código HTML en una pantalla de computadora"
width="800" height="400">
<figcaption>HTML es el punto de partida de todo sitio web.</figcaption>
</figure>
<section>
<h2>¿Por qué aprender HTML primero?</h2>
<p>HTML es <strong>la base de todo en la web</strong>.
Sin HTML no hay CSS ni JavaScript posibles.</p>
</section>
<section>
<h2>Recursos recomendados</h2>
<ul>
<li><a href="https://mdn.web.docs">MDN Web Docs</a></li>
<li><a href="https://web.dev">web.dev de Google</a></li>
</ul>
</section>
</article>
<aside aria-label="Artículos relacionados">
<h2>También te puede interesar</h2>
<ul>
<li><a href="/css-basico">CSS para principiantes</a></li>
<li><a href="/javascript-intro">Introducción a JavaScript</a></li>
</ul>
</aside>
</main>
<footer>
<p><small>© 2026 Mi Blog de Programación.</small></p>
<nav aria-label="Navegación del pie">
<a href="/privacidad">Política de privacidad</a>
</nav>
</footer>
</body>
</html>
Probá el Ejemplo 4: Página de artículo completa
Buenas Prácticas
- lang en el <html>: siempre
<html lang="es">— los lectores de pantalla lo usan para la pronunciación - Un solo <main> por página: y siempre con un id para el skip link
- Jerarquía de encabezados sin saltar niveles: h1 → h2 → h3, nunca h1 → h4
- aria-label en navegaciones: si hay más de una
<nav>, identificalas conaria-label - aria-current="page": en el enlace de la página activa para que los lectores de pantalla lo anuncien
- Validá tu HTML: usá el validador de W3C (
validator.w3.org) para encontrar errores estructurales - Probá con un lector de pantalla: NVDA (Windows, gratis) o VoiceOver (Mac/iOS) para verificar la experiencia real