Ver contenido
Guía de Implementación de Alt Text: Referencia Técnica Completa
Introducción
Esta guía completa cubre la implementación técnica de texto alternativo para todos los tipos de imágenes y contextos. Desde imágenes decorativas simples hasta infografías complejas, aprenderás las técnicas específicas requeridas para cumplimiento WCAG y accesibilidad óptima.
Categorías de Imágenes y Técnicas
El Árbol de Decisión WAI para Imágenes
┌─────────────────────────────────────────────────────────┐
│ DECISIÓN DE ACCESIBILIDAD DE IMÁGENES WAI │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. ¿La imagen contiene texto? │
│ └─ SÍ → Incluir texto en alt │
│ │
│ 2. ¿La imagen se usa en un enlace o botón? │
│ └─ SÍ → Describir función/destino │
│ │
│ 3. ¿La imagen contribuye significado al contexto? │
│ └─ SÍ → Describir contenido informativo │
│ │
│ 4. ¿La imagen es puramente decorativa? │
│ └─ SÍ → Usar alt nulo (alt="") │
│ │
│ 5. ¿La imagen es compleja (gráficos, diagramas)? │
│ └─ SÍ → Proporcionar descripción larga │
│ │
└─────────────────────────────────────────────────────────┘
Implementación por Tipo de Imagen
1. Imágenes Informativas
Imágenes que transmiten información o conceptos:
<!-- Imagen informativa simple -->
<img
src="icono-advertencia.png"
alt="Advertencia: Esta acción no se puede deshacer"
>
<!-- Foto con contexto -->
<img
src="edificio-oficinas.jpg"
alt="Edificio de oficinas moderno de cristal con logo de empresa en entrada"
>
<!-- Visualización de datos -->
<img
src="tendencia.png"
alt="Flecha de tendencia ascendente indicando crecimiento"
>
2. Imágenes Decorativas
Imágenes que no agregan contenido informativo:
<!-- Método 1: Atributo alt vacío (preferido) -->
<img src="borde-decorativo.png" alt="">
<!-- Método 2: Fondo CSS (verdaderamente decorativo) -->
<style>
.hero {
background-image: url('patron-abstracto.png');
}
</style>
<!-- Método 3: Role presentation (ARIA) -->
<img src="adorno.svg" alt="" role="presentation">
¿Cuándo es una imagen decorativa?
- Patrones y texturas de fondo
- Elementos espaciadores o de diseño
- Íconos junto a texto que dice lo mismo
- Imágenes de ambiente que no agregan información
3. Imágenes Funcionales
Imágenes usadas como enlaces, botones o controles:
<!-- Logo enlazado -->
<a href="/">
<img src="logo.png" alt="Nombre de Empresa - Ir a inicio">
</a>
<!-- Botón de imagen -->
<button type="submit">
<img src="icono-buscar.svg" alt="Buscar">
</button>
<!-- Enlace de imagen -->
<a href="/carrito">
<img src="icono-carrito.svg" alt="Carrito de compras (3 artículos)">
</a>
<!-- Botón de imprimir -->
<button onclick="window.print()">
<img src="imprimir.svg" alt="Imprimir esta página">
</button>
4. Imágenes de Texto
Imágenes que contienen texto legible:
<!-- Logo con texto -->
<img src="logo.png" alt="Acme Corporation">
<!-- Banner con mensaje -->
<img
src="banner-oferta.jpg"
alt="Ofertas de Verano: 50% de descuento en todos los artículos hasta el 31 de agosto"
>
<!-- Encabezado estilizado -->
<img
src="texto-bienvenida.png"
alt="Bienvenido a Nuestra Tienda"
>
Mejor Práctica: Usa texto real con estilos CSS en lugar de imágenes de texto cuando sea posible.
5. Imágenes Complejas
Gráficos, diagramas, tablas e infografías:
<!-- Método 1: Alt breve + atributo longdesc -->
<img
src="organigrama.png"
alt="Organigrama mostrando estructura de la empresa"
longdesc="descripcion-organigrama.html"
>
<!-- Método 2: Alt breve + descripción de texto adyacente -->
<figure>
<img
src="grafico-ventas.png"
alt="Gráfico de ventas trimestrales - detalles en tabla abajo"
>
<figcaption>
<details>
<summary>Descripción de datos de ventas</summary>
<p>Q1: $1.2M, Q2: $1.5M, Q3: $1.8M, Q4: $2.1M.
Crecimiento total del 75% año tras año.</p>
</details>
</figcaption>
</figure>
<!-- Método 3: aria-describedby -->
<img
src="flujo-proceso.png"
alt="Proceso de checkout en 5 pasos"
aria-describedby="descripcion-proceso"
>
<div id="descripcion-proceso" class="sr-only">
Paso 1: Agregar artículos al carrito.
Paso 2: Ingresar dirección de envío.
Paso 3: Seleccionar método de envío.
Paso 4: Ingresar información de pago.
Paso 5: Revisar y confirmar pedido.
</div>
6. Grupos de Imágenes
Múltiples imágenes transmitiendo una sola pieza de información:
<!-- Calificación por estrellas -->
<div role="img" aria-label="Calificación: 4 de 5 estrellas">
<img src="estrella-llena.svg" alt="">
<img src="estrella-llena.svg" alt="">
<img src="estrella-llena.svg" alt="">
<img src="estrella-llena.svg" alt="">
<img src="estrella-vacia.svg" alt="">
</div>
<!-- Colección de imágenes -->
<figure role="group" aria-label="Vistas del producto">
<img src="frente.jpg" alt="Vestido azul - vista frontal">
<img src="atras.jpg" alt="Vestido azul - vista trasera">
<img src="detalle.jpg" alt="Vestido azul - detalle de tela">
</figure>
7. Mapas de Imagen
Regiones clickeables dentro de una imagen:
<img
src="plano-oficina.png"
alt="Plano de oficina con departamentos clickeables"
usemap="#mapa-plano"
>
<map name="mapa-plano">
<area
shape="rect"
coords="0,0,100,100"
href="/ventas"
alt="Departamento de Ventas"
>
<area
shape="rect"
coords="100,0,200,100"
href="/ingenieria"
alt="Departamento de Ingeniería"
>
<area
shape="rect"
coords="200,0,300,100"
href="/rrhh"
alt="Recursos Humanos"
>
</map>
Implementación Específica por Framework
React/Next.js
// Imagen estándar con alt
function ProductImage({ product }) {
return (
<img
src={product.imageUrl}
alt={`${product.name} - ${product.color} ${product.category}`}
/>
);
}
// Componente Image de Next.js
import Image from 'next/image';
function HeroImage() {
return (
<Image
src="/hero.jpg"
alt="Equipo colaborando en proyecto de diseño"
width={1200}
height={600}
priority
/>
);
}
// Imagen decorativa en React
function DecorativeDivider() {
return (
<img
src="/divisor.svg"
alt=""
role="presentation"
aria-hidden="true"
/>
);
}
Vue.js
<template>
<!-- Imagen informativa -->
<img
:src="product.image"
:alt="`${product.name} - ${product.description}`"
/>
<!-- Imagen decorativa -->
<img
src="/decorativo.svg"
alt=""
aria-hidden="true"
/>
<!-- Imagen compleja con descripción -->
<figure>
<img
:src="chart.src"
:alt="chart.briefDescription"
:aria-describedby="`chart-desc-${chart.id}`"
/>
<figcaption :id="`chart-desc-${chart.id}`">
{{ chart.longDescription }}
</figcaption>
</figure>
</template>
Accesibilidad SVG
<!-- SVG decorativo -->
<svg aria-hidden="true" focusable="false">
<!-- ... -->
</svg>
<!-- SVG informativo -->
<svg role="img" aria-labelledby="svg-titulo svg-desc">
<title id="svg-titulo">Estadísticas de Usuarios</title>
<desc id="svg-desc">Gráfico de barras mostrando crecimiento de usuarios en 12 meses</desc>
<!-- ... -->
</svg>
<!-- SVG interactivo -->
<svg role="img" aria-label="Menú de navegación">
<!-- ... -->
</svg>
Testing de Alt Text
Testing Automatizado
// Cypress con axe-core
describe('Accesibilidad de Imágenes', () => {
it('debe tener alt text apropiado en todas las imágenes', () => {
cy.visit('/');
cy.injectAxe();
cy.checkA11y(null, {
rules: {
'image-alt': { enabled: true },
'input-image-alt': { enabled: true },
'area-alt': { enabled: true }
}
});
});
});
// Jest con jest-axe
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('imágenes tienen alt text', async () => {
const html = render(<ProductPage />);
const results = await axe(html.container);
expect(results).toHaveNoViolations();
});
Checklist de Testing Manual
## Checklist de Auditoría de Alt Text
### Para Cada Imagen:
- [ ] Tiene atributo alt (nunca faltante)
- [ ] Alt text describe propósito, no apariencia
- [ ] Alt es conciso (menos de 125 caracteres cuando sea posible)
- [ ] Imágenes decorativas usan alt=""
- [ ] Imágenes enlazadas describen destino
- [ ] Imágenes complejas tienen descripciones largas
### Verificaciones a Nivel de Página:
- [ ] Deshabilitar imágenes - ¿es entendible el contenido?
- [ ] Test con lector de pantalla - ¿las imágenes tienen sentido?
- [ ] Sin alt text duplicado en diferentes imágenes
- [ ] Sin imágenes de texto (usar texto real en su lugar)
Comandos de Testing con Lectores de Pantalla
VoiceOver (macOS):
- VO + Command + I → Listar todas las imágenes en página
- VO + Flecha Derecha → Navegar al siguiente elemento
NVDA (Windows):
- G → Saltar a siguiente gráfico
- Shift + G → Saltar a gráfico anterior
- NVDA + F7 → Lista de elementos (seleccionar Imágenes)
JAWS (Windows):
- G → Saltar a siguiente gráfico
- Shift + G → Saltar a gráfico anterior
- Insert + F7 → Lista de gráficos
Consideraciones de CMS y Plataforma
WordPress
// Forzar requisito de alt text
add_filter('attachment_fields_to_edit', function($fields, $post) {
$fields['alt_text_required'] = array(
'label' => 'Alt Text (Requerido)',
'input' => 'text',
'value' => get_post_meta($post->ID, '_wp_attachment_image_alt', true),
'helps' => 'Describe esta imagen para accesibilidad'
);
return $fields;
}, 10, 2);
Shopify
{% comment %} Imagen de producto con alt dinámico {% endcomment %}
<img
src="{{ product.featured_image | img_url: 'large' }}"
alt="{{ product.featured_image.alt | default: product.title }}"
loading="lazy"
>
Patrones Comunes
Imágenes de Productos E-commerce
<!-- Imagen principal de producto -->
<img
src="producto-principal.jpg"
alt="Chaqueta de mezclilla azul, vista frontal, tallas XS-XXL"
>
<!-- Galería de miniaturas -->
<div role="group" aria-label="Galería de imágenes del producto">
<button aria-pressed="true">
<img src="thumb-1.jpg" alt="Vista frontal">
</button>
<button aria-pressed="false">
<img src="thumb-2.jpg" alt="Vista trasera">
</button>
<button aria-pressed="false">
<img src="thumb-3.jpg" alt="Vista lateral mostrando bolsillos">
</button>
</div>
Avatares de Usuario
<!-- Con nombre de usuario -->
<img
src="avatar.jpg"
alt=""
aria-hidden="true"
>
<span>Juan Pérez</span>
<!-- Avatar independiente -->
<img
src="avatar.jpg"
alt="Foto de perfil de Juan Pérez"
>
Íconos con Texto
<!-- Ícono + texto visible (ícono es decorativo) -->
<button>
<img src="icono-guardar.svg" alt="" aria-hidden="true">
<span>Guardar Documento</span>
</button>
<!-- Solo ícono (ícono es funcional) -->
<button aria-label="Guardar documento">
<img src="icono-guardar.svg" alt="">
</button>
Guías de Calidad
Longitud del Alt Text
| Contexto | Longitud Recomendada | Ejemplo |
|---|---|---|
| Imagen simple | 10-50 caracteres | “Ícono de advertencia rojo” |
| Foto de producto | 50-100 caracteres | “Audífonos inalámbricos azules con cancelación de ruido” |
| Gráfico complejo | Alt breve + descripción larga | “Gráfico de ventas - ver tabla abajo para datos” |
| Decorativa | 0 caracteres | alt=“” |
Escribiendo Alt Text de Calidad
Buenos Ejemplos:
<img alt="Gráfico mostrando 150% de aumento de ingresos de enero a diciembre 2024">
<img alt="Dra. Sara Chen presentando en la conferencia anual de tecnología">
<img alt="Paso 3: Click en el botón azul Enviar en la esquina superior derecha">
Malos Ejemplos:
<img alt="gráfico"> <!-- Muy vago -->
<img alt="imagen"> <!-- Sin significado -->
<img alt="foto de persona"> <!-- ¿Quién? ¿Haciendo qué? -->
<img alt="IMG_2847.jpg"> <!-- Nombre de archivo, no descripción -->
Artículos Relacionados
- Alt Text Explicado - Introducción al alt text
- Hub de Cumplimiento WCAG - Guía completa de accesibilidad
- Guía de Etiquetas ARIA - Técnicas avanzadas de etiquetado
Referencias
- W3C - WCAG 2.2 SC 1.1.1 Contenido No Textual
- W3C - Tutorial de Imágenes WAI
- W3C - Patrón de Imágenes ARIA
- WebAIM - Texto Alternativo
- Deque - Accesibilidad de Imágenes