01 — Fundamentos
No es solo HTML. Es comunicación.
El HTML que escribes lo leen tres tipos de "usuarios": el navegador, los motores de búsqueda (Google) y los lectores de pantalla (para personas con discapacidad visual). Si usas <div> para todo, solo el humano frente a la pantalla entiende algo. Los otros dos están en la oscuridad.
Los robots de indexación entienden <article> pero no saben qué es un <div class="post">. HTML semántico mejora directamente tu posicionamiento en buscadores.
Lectores de pantalla
JAWS, NVDA, VoiceOver leen el HTML en voz alta. Con <button> saben que es interactivo. Con un <div onclick> no anuncian nada. Hay 285 millones de personas con discapacidad visual.
Otros desarrolladores
Código semántico es código mantenible. Cuando un compañero lee tu HTML entiende la estructura sin leer el CSS. Eso ahorra horas en equipos reales.
02 — Estructura
La anatomía de cualquier web
Toda página web bien construida tiene la misma estructura. No como convención, sino porque así funciona el modelo semántico de HTML5.
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="Descripción de la página para Google"> <title>Mi sitio — Título para la pestaña y Google</title> <link rel="stylesheet" href="styles.css"> </head> <body> <header> <!-- Cabecera del sitio --> <nav> <!-- Navegación principal --> <a href="/">Inicio</a> <a href="/about">Sobre mí</a> </nav> </header> <main> <!-- Contenido principal (ÚNICO en la página) --> <section> <!-- Sección temática con su propio heading --> <h1>Título principal de la página</h1> <p>Contenido...</p> </section> <aside> <!-- Contenido relacionado pero secundario --> <h2>Artículos relacionados</h2> </aside> </main> <footer> <!-- Pie de página --> <p>© 2024 Mi sitio</p> </footer> </body> </html>
<header>
Cabecera del sitio o de una sección (article/section)
Puede haber varios en la página, pero solo uno para el sitio
<nav>
Bloques de navegación principal o secundaria
Solo los links de navegación importantes, no todos los links
<main>
El contenido único y principal de la página
Solo UNO por página. Nunca dentro de header, footer o aside
<section>
Agrupación temática de contenido con su propio heading
Si no tiene un heading, probablemente sea un div
<article>
Contenido independiente y redistribuible: post, producto, comentario
¿Tiene sentido solo, fuera de contexto? Entonces es article
<aside>
Contenido relacionado pero secundario: sidebars, anuncios, widgets
No es solo "barra lateral". Es contenido opcionalmente relacionado
<footer>
Pie de sitio o de una sección
Puede contener copyright, links secundarios, contact info
<h1>–<h6>
Jerarquía de headings del contenido
Un solo h1 por página. No saltes niveles (h1 → h3)
03 — Contenedores
La pregunta que confunde a todos
Estos tres elementos se confunden constantemente. Aquí la regla simple: pregúntate qué es el contenido, no cómo se ve visualmente.
¿Es contenido independiente?
<article>
Un post, una tarjeta de producto, un comentario. Puede vivir fuera de la página y tener sentido completo.
→ Cada tweet en un feed→ Cada card de producto
→ Cada post de blog
→ Cada comentario en un foro
¿Es una sección temática con heading?
<section>
Agrupa contenido relacionado bajo un tema. Siempre debe tener un heading (h2, h3...) que lo identifique.
→ <section id="features">→ <section id="testimonios">
→ <section id="precios">
→ <section id="contacto">
¿Es solo un contenedor para CSS/JS?
<div>
Cuando no hay significado semántico. Solo para agrupar cosas por motivos visuales o de JavaScript.
→ <div class="flex-container">→ <div class="modal-overlay">
→ <div class="grid-wrapper">
→ <div id="app">
Regla práctica: ¿Puedo copiar este bloque de HTML y pegarlo en otra página y que tenga sentido? Si sí → <article>. ¿Tiene un título propio que describe su tema? → <section>. ¿No tiene ningún significado semántico propio? → <div>.
04 — Formularios
Formularios: el elemento más mal usado de HTML
Los formularios son donde más errores semánticos se acumulan. Un formulario correcto funciona sin JavaScript, es accesible por teclado y tiene validación nativa del navegador.
<div class="form"> <div>Nombre:</div> <input type="text" placeholder="Tu nombre"> <div>Email:</div> <input type="text" placeholder="tu@email.com"> <div onclick="sendForm()"> Enviar </div> </div>
- Sin
<form>: no funciona con Enter, sin submit nativo - Texto sin
<label>: lectores de pantalla ciegos al input type="text"para email: sin validación de formato<div onclick>como botón: no funciona con teclado
<form action="/subscribe" method="POST"> <label for="nombre"> Nombre completo <span aria-hidden="true">*</span> </label> <input type="text" id="nombre" name="nombre" required autocomplete="name" placeholder="Ej: Ana García" > <label for="email">Email</label> <input type="email" id="email" name="email" required autocomplete="email" > <button type="submit"> Suscribirse </button> </form>
<form>correcto: submit con Enter, semántica completa<label for>vinculado aliddel inputtype="email"valida formato en navegador y móvil<button type="submit">: accesible por teclado
type="text"
Texto genérico
autocomplete="name"
type="email"
Email (valida @ en móvil/desktop)
autocomplete="email"
type="password"
Contraseña (oculta el texto)
autocomplete="current-password"
type="number"
Números con min/max/step
min="0" max="100"
type="tel"
Teléfono (teclado numérico en móvil)
autocomplete="tel"
type="date"
Selector de fecha nativo
min="2024-01-01"
type="checkbox"
Opción múltiple
checked para preseleccionar
type="radio"
Opción única del grupo
name agrupa los radios
type="file"
Subida de archivos
accept=".pdf,.jpg"
type="range"
Slider numérico
min max step value
type="search"
Campo de búsqueda
Semántica para buscadores
type="url"
URL (valida formato http://)
autocomplete="url"
05 — Accesibilidad
Accesibilidad: código para todos
No es un extra. En muchos países es un requisito legal. Y mejora tu SEO. Los tres atributos que más diferencia hacen:
alt en imágenes
El texto que se muestra cuando la imagen no carga y que leen los lectores de pantalla. Si la imagen es decorativa, usa alt vacío para que el lector de pantalla la ignore completamente.
<!-- Imagen informativa: describe el contenido --> <img src="equipo.jpg" alt="El equipo de Vitesse Stack en la oficina de Bogotá"> <!-- Imagen decorativa: alt vacío, no se anuncia --> <img src="decoracion.svg" alt=""> <!-- Icono con función: describe la acción, no el icono --> <button> <img src="search.svg" alt="Buscar"> </button>
aria-label y aria-describedby
Cuando el elemento visual no tiene texto visible suficiente para describirse, estos atributos proporcionan el nombre o descripción accesible al árbol de accesibilidad.
<!-- Botón con solo icono --> <button aria-label="Cerrar modal"> <svg><!-- icono X --></svg> </button> <!-- Input con descripción adicional --> <label for="pwd">Contraseña</label> <input type="password" id="pwd" aria-describedby="pwd-hint"> <p id="pwd-hint"> Mínimo 8 caracteres, una mayúscula y un número. </p> <!-- Región con label --> <nav aria-label="Navegación principal"> <a href="/">Inicio</a> </nav>
Jerarquía de headings
Google y los lectores de pantalla usan los headings para construir el índice de la página. La jerarquía debe ser lógica, nunca saltar niveles.
h1 — Título del sitio
h3 — ¡Saltamos h2!
h2 — ¡Volvemos atrás!
h4 — Sub-sub
h1 — Título del sitio (solo uno)
h2 — Sección principal
h3 — Subsección
h3 — Subsección
h2 — Otra sección principal
06 — SEO
Meta tags: lo que Google y las redes sociales leen
El <head> no es solo para el <title>. Estos meta tags afectan directamente cómo aparece tu web en Google y cómo se ve al compartirla en WhatsApp, Twitter o LinkedIn.
<head> <!-- BÁSICOS (siempre) --> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="Descripción de 150-160 caracteres para Google"> <title>Nombre de la página — Nombre del sitio</title> <link rel="canonical" href="https://misitioweb.com/esta-pagina/"> <!-- OPEN GRAPH (WhatsApp, Facebook, LinkedIn) --> <meta property="og:title" content="Título al compartir"> <meta property="og:description" content="Descripción al compartir"> <meta property="og:image" content="https://misitioweb.com/preview.jpg"> <meta property="og:url" content="https://misitioweb.com/esta-pagina/"> <meta property="og:type" content="website"> <!-- TWITTER CARD --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:title" content="Título para Twitter"> <meta name="twitter:image" content="https://misitioweb.com/preview.jpg"> </head>
07 — Ejercicio
Ejercicio: estructura semántica de un blog
Construirás el HTML completo de un blog de tecnología. Sin CSS, sin JavaScript. Solo HTML semántico correcto. El objetivo es que sea perfectamente accesible y que Google entienda la estructura.
Blog de tecnología con 3 artículos
Un header con nav, un main con section para artículos destacados, cada artículo como article con h2, byline, resumen y link de lectura. Un aside con categorías. Un footer con copyright y links secundarios.
Estructura base
DOCTYPE, html con lang="es", head completo con meta description y title descriptivo. No hay CSS todavía.
15 minHeader y navegación
header con el nombre del blog, nav con los links principales (Inicio, Categorías, Sobre mí). Usa aria-label en el nav.
15 minMain con artículos
main > section con h1, luego tres article anidados. Cada article tiene h2, p.byline (autor, fecha), p.resumen, y a "Leer más" con aria-label descriptivo.
30 minAside y footer
aside con h2 "Categorías" y lista de links. footer con dirección, copyright y nav secundario para links legales.
15 minValidación
Pega tu HTML en validator.w3.org y corrige todos los errores. Luego instala el Chrome extension "axe DevTools" y ejecuta el audit de accesibilidad.
15 min08 — Recursos
Recursos de esta sesión
Todo lo que necesitas para profundizar después de la clase.
MDN — Referencia de elementos HTML
El catálogo completo de todas las etiquetas HTML con descripción, atributos y ejemplos.
W3C Validator — Valida tu HTML
Pega tu HTML y detecta todos los errores. Úsalo al terminar cada ejercicio.
axe DevTools — Auditoría de accesibilidad
Extension de Chrome que encuentra problemas de accesibilidad en cualquier web.
HTML5 Doctor — Guía de uso de elementos
Explica cuándo usar cada elemento semántico con ejemplos reales.
HTML Semántico en profundidad — Kevin Powell
El video más completo en inglés sobre semántica HTML. Kevin Powell es el mejor profesor de CSS/HTML en YouTube.