En esta página
Accesibilidad web básica con HTML
Qué es la accesibilidad web?
La accesibilidad web (a menudo abreviada como a11y) significa disenar y desarrollar páginas que puedan ser usadas por todas las personas, incluyendo aquellas con discapacidades visuales, auditivas, motoras o cognitivas.
Segun la Organizacion Mundial de la Salud, más del 15% de la poblacion mundial vive con alguna forma de discapacidad. Hacer tu sitio accesible no es solo una buena práctica -- en muchos paises es un requisito legal.
Las 4 principios de la accesibilidad (POUR)
Las WCAG se basan en cuatro principios fundamentales:
- Perceptible — La información debe poder ser percibida (ver, oir, leer)
- Operable — La interfaz debe poder usarse con diferentes dispositivos (teclado, voz)
- Comprensible — El contenido y la interfaz deben ser entendibles
- Robusto — El contenido debe funcionar con diferentes tecnologias asistivas
Texto alternativo en imagenes
El atributo alt es la herramienta principal de accesibilidad para imagenes:
<!-- Imagen informativa: describir el contenido -->
<img src="grafico.png" alt="Grafico de barras mostrando un aumento del 25% en ventas">
<!-- Imagen decorativa: alt vacio -->
<img src="borde-decorativo.png" alt="">
<!-- Imagen funcional (boton/enlace): describir la accion -->
<a href="/inicio">
<img src="logo.svg" alt="Ir a página de inicio">
</a>La regla es simple:
- Si la imagen transmite información, describe esa información
- Si la imagen es decorativa, usa
alt=""(vacio, no omitir el atributo) - Si la imagen esta dentro de un enlace o boton, describe la accion
Estructura de encabezados
Los encabezados (<h1> a <h6>) crean un esquema (outline) de la página que los lectores de pantalla usan para navegar. Los usuarios pueden saltar entre encabezados como si fuera un índice:
<h1>Curso de HTML</h1>
<h2>Capítulo 1: Introducción</h2>
<h3>Que es HTML?</h3>
<h3>Historia de HTML</h3>
<h2>Capítulo 2: Elementos básicos</h2>
<h3>Etiquetas de texto</h3>Reglas esenciales:
- No saltes niveles (no pases de
<h2>a<h4>) - Un solo
<h1>por página - Los encabezados deben reflejar la jerarquia lógica del contenido
Navegación con teclado
Muchos usuarios navegan exclusivamente con el teclado (Tab, Enter, Escape, flechas). Asegurate de que:
Todos los elementos interactivos son enfocables
Los elementos nativos de HTML como <a>, <button>, <input> y <select> son enfocables por defecto. Si creas elementos interactivos con <div> o <span>, no serán enfocables a menos que agregues tabindex="0":
<!-- Correcto: boton nativo, enfocable automaticamente -->
<button type="button">Abrir menu</button>
<!-- Incorrecto: div no enfocable ni accesible -->
<div class="boton" onclick="abrirMenu()">Abrir menu</div>
<!-- Mejor: usa elementos nativos siempre que sea posible -->Skip links
Un "skip link" permite a usuarios de teclado saltar directamente al contenido principal sin tener que tabular por toda la navegación:
<body>
<a href="#main" class="skip-link">Saltar al contenido principal</a>
<nav><!-- muchos enlaces de navegación --></nav>
<main id="main">
<!-- contenido principal -->
</main>
</body>Formularios accesibles
Los formularios son una de las areas más críticas de accesibilidad:
Labels explicitos
Todo campo de formulario debe tener una etiqueta <label> asociada:
<!-- Asociacion explícita con for/id -->
<label for="usuario">Nombre de usuario</label>
<input type="text" id="usuario" name="usuario">
<!-- Asociacion implícita (label envuelve al input) -->
<label>
Correo electronico
<input type="email" name="email">
</label>Descripciones adicionales con aria-describedby
Cuando un campo necesita instrucciones adicionales:
<label for="password">Contrasena</label>
<input type="password" id="password" aria-describedby="password-req">
<p id="password-req">Minimo 8 caracteres, incluir un número y una mayuscula.</p>Grupos de campos relacionados
Usa <fieldset> y <legend> para agrupar campos relacionados:
<fieldset>
<legend>Direccion de envio</legend>
<label for="calle">Calle</label>
<input type="text" id="calle" name="calle">
<label for="ciudad">Ciudad</label>
<input type="text" id="ciudad" name="ciudad">
</fieldset>Atributos ARIA esenciales
ARIA (Accessible Rich Internet Applications) proporciona atributos que mejoran la accesibilidad cuando el HTML nativo no es suficiente:
| Atributo | Uso |
|---|---|
aria-label |
Nombre accesible cuando no hay texto visible |
aria-labelledby |
Referencia a un elemento que actua como label |
aria-describedby |
Referencia a un elemento con descripción adicional |
aria-required |
Indica que un campo es obligatorio |
aria-hidden |
Oculta un elemento de tecnologias asistivas |
aria-current |
Indica el elemento actual en un conjunto (página activa, paso actual) |
role |
Define el rol semántico de un elemento |
La regla de ARIA más importante: no uses ARIA si puedes lograr lo mismo con HTML nativo. Un <button> es mejor que un <div role="button">.
Contraste de color
El contraste entre el texto y el fondo debe cumplir las siguientes ratios (WCAG AA):
- Texto normal: ratio mínimo de 4.5:1
- Texto grande (18px bold o 24px normal): ratio mínimo de 3:1
- Elementos de interfaz (bordes, iconos): ratio mínimo de 3:1
Herramientas como el inspector de accesibilidad de Chrome DevTools te permiten verificar el contraste directamente en tu navegador.
Práctica
- Agrega un skip link: Crea una página con navegación extensa y anade un enlace "Saltar al contenido principal" como primer elemento del
<body>que apunte aliddel<main>. - Construye un formulario accesible: Crea un formulario de contacto donde cada
<input>tenga un<label>asociado confor/id, al menos un campo usearia-describedbypara instrucciones adicionales, y los radio buttons estén dentro de un<fieldset>con<legend>. - Audita las imagenes: Revisa una página existente y asegurate de que todas las imagenes informativas tengan un
altdescriptivo y las decorativas tenganalt="".
En la siguiente leccion aprenderemos a construir formularios completos y funcionales.
<!-- Formulario accesible -->
<form aria-labelledby="form-título">
<h2 id="form-título">Formulario de contacto</h2>
<div>
<label for="nombre">Nombre completo *</label>
<input
type="text"
id="nombre"
name="nombre"
required
autocomplete="name"
aria-required="true"
>
</div>
<div>
<label for="email">Correo electronico *</label>
<input
type="email"
id="email"
name="email"
required
autocomplete="email"
aria-required="true"
aria-describedby="email-hint"
>
<small id="email-hint">Ejemplo: [email protected]</small>
</div>
<div role="group" aria-labelledby="preferencia-label">
<p id="preferencia-label">Método de contacto preferido:</p>
<label>
<input type="radio" name="contacto" value="email"> Email
</label>
<label>
<input type="radio" name="contacto" value="telefono"> Telefono
</label>
</div>
<button type="submit">Enviar mensaje</button>
</form>
<!-- Skip link para saltar al contenido -->
<a href="#contenido-principal" class="skip-link">
Saltar al contenido principal
</a>
<header>
<nav aria-label="Menu principal">
<ul role="list">
<li><a href="/" aria-current="page">Inicio</a></li>
<li><a href="/cursos">Cursos</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
</header>
<main id="contenido-principal">
<h1>Bienvenido al sitio</h1>
<!-- Imagen informativa -->
<img src="equipo.jpg"
alt="Nuestro equipo de 5 desarrolladores en la oficina"
width="800" height="450">
<!-- Imagen decorativa -->
<img src="decoracion.svg" alt="" role="presentation">
<!-- Icono con texto alternativo -->
<button type="button" aria-label="Cerrar diálogo">
<svg aria-hidden="true" focusable="false">
<!-- icono X -->
</svg>
</button>
</main>
Inicia sesión para guardar tu progreso