🇺🇸 EN
Frontend
·7 min read·↗·🇺🇸 EN

Accesibilidad web: trabajando con imágenes y contenido

Portada principal del artículo: Accesibilidad web: trabajando con imágenes y contenido

Cuando creamos un sitio web, el contenido es mucho más que simple texto. Como aprendí en mi artículo anterior, la accesibilidad va más allá de colocar atributos aria-label o alt en las imágenes. A veces agregamos otros elementos como SVGs o gráficos de estadísticas, o incluso debemos prestar atención al contraste o a un fondo con demasiado brillo.

Cuando pensamos en accesibilidad, lo primero que suele venir a la mente es la ceguera. Pero ¿qué pasa si alguien sufre un accidente y no puede usar el mouse, si está en un lugar con demasiada luz solar, o si tiene problemas de visión tras una cirugía y le cuesta leer el texto (sé lo que se siente por experiencia propia)?

Hoy quiero compartir contigo lo que he aprendido sobre accesibilidad en estos últimos días. ¡Vamos a verlo!

Si quieres probar todos estos casos, te recomiendo mucho usar un lector de pantalla como VoiceOver para usuarios de Mac o NVDA para Windows.

Tipos de imágenes

Cuando agregamos imágenes a nuestros sitios web, algunas cumplen un propósito funcional mientras que otras son puramente decorativas. ¿Cuál es la diferencia?

  • Decorativas: Funcionan como elementos de estilo o para hacer la interfaz más atractiva sin transmitir un texto o mensaje, como un fondo decorativo. Estas imágenes no son necesarias para la funcionalidad ni para comunicar información relevante.

  • Funcionales: Se incluyen en la aplicación porque son útiles para realizar una acción, como íconos de redes sociales, imágenes que contienen información como texto o gráficos de estadísticas, o banners promocionales con un botón para registrarse u obtener un descuento.

Cómo manejar imágenes decorativas

Para la accesibilidad, las imágenes decorativas no son relevantes. Si una persona usa un lector de pantalla, escuchar la descripción de una imagen que solo sirve de fondo no aporta valor. Por eso, es fundamental indicar que la imagen es decorativa usando alt="" (vacío), sin título ni atributo role, para que el lector de pantalla la ignore por completo.

Por ejemplo:

<main>
    <img src="fancy-background.jpg" alt=""/>
</main>

Si dejas la imagen sin el atributo alt, como en <img src="fancy-background.jpg"/>, el lector de pantalla anunciará el archivo al usuario, interrumpiendo la lectura.

Cómo manejar imágenes funcionales

¿Qué es una imagen funcional? Son imágenes que cumplen una función concreta dentro de la aplicación, como una promoción con enlace de referido y descuento, íconos de redes sociales o gráficos con estadísticas.

La información clave se proporciona a través del atributo alt. Por ejemplo, en el siguiente código, el lector de pantalla pasa por alto la imagen decorativa del borde y anuncia "LeBron James NBA Player".

<main>
    <img src="fancy-border.jpg" alt=""/>
    <img src="lebron-james.jpg" alt="LeBron James NBA Player"/>
</main>

A veces tenemos imágenes fuera del viewport que solo se muestran después de ejecutar código JavaScript. Aunque la imagen no sea visible en pantalla, el lector de pantalla sigue leyendo la estructura HTML.

Para asegurarnos de que el lector ignore estas imágenes hasta que sea necesario, podemos usar la propiedad CSS display: none o los atributos hidden o aria-hidden.

En los siguientes ejemplos, el lector de pantalla ignorará la imagen:

<main>
    <h1>The NBA</h1>
    <img src="lebron-james.jpg" alt="LeBron James NBA Player" aria-hidden />
    <img src="lebron-james.jpg" alt="LeBron James NBA Player" hidden />
</main>

¿Sabías que el texto alt también ayuda al SEO? 😎

¿Cómo hacer imágenes accesibles en CSS?

La mayoría de imágenes de fondo e íconos se definen mediante CSS o fuentes de íconos. Mi recomendación es usar imágenes en CSS únicamente con fines decorativos y no funcionales. Sin embargo, en el mundo real esto no siempre se cumple.

Por ejemplo, aquí tenemos una imagen de fondo definida en CSS:

.logo {
  background-image: url('../logo.png');
  background-repeat: no-repeat, repeat;
  height: 24em;
  width: 100%;
}

Ahora puedo aplicarla a varios elementos y personalizarla según el caso.

El atributo aria-label funciona de forma similar a alt. No es visible para los usuarios en pantalla, pero el lector de pantalla transmite esta información junto con cualquier contenido adicional dentro del elemento:

<span class="logo" aria-label="Welcome to NBA">
Purchase game now!
</span>
<div class="logo" aria-label="Welcome to NBA">
Purchase game now!
</div>

Este enfoque funciona, pero le estamos dando demasiada responsabilidad al span y al div, obligándolos a mostrar el fondo y contener el texto al mismo tiempo. Además, no se integra bien con elementos que tienen un rol semántico específico, como los botones.

Una solución más limpia es reestructurar nuestro HTML usando un elemento dedicado a una sola tarea.

Por ejemplo:

<div>
    Purchase game now!
    <span class="logo" aria-label="Welcome to NBA"></span>
</div>
<button>
    Purchase <span class="logo" aria-label="Welcome to NBA"></span>
</button>

¿Cómo proporcionar toda la información?

En los ejemplos anteriores el caso es directo porque se trata de una sola imagen o un botón. Pero ¿qué ocurre con una imagen con estadísticas de la NBA que contiene muchos datos del partido? ¿Debo escribir un texto larguísimo en el alt?

Por ejemplo, mira la siguiente imagen:

<img src="./gianis.png" alt="Giannis Antetokounmpo Game Stats">

Agregamos la imagen y usamos el atributo alt para describirla, pero muchos detalles de las estadísticas se quedan fuera. Una alternativa es agregar una etiqueta p con la información adicional:

<img src="./gianis.png" alt="Giannis Antetokounmpo Breaks Record">
<p>Giannis Antetokounmpo becomes the first player to have 45 points, 10 rebounds, 5 assists, and 0 turnovers in a game since Michael Jordan in 1989!</p>

Esto funciona, pero los usuarios videntes verán la información duplicada en pantalla. ¿Cómo podemos resolverlo?

En estos casos, una buena solución es ocultar el texto visualmente del viewport. Por ejemplo, si usas Kendo UI, cuentas con la clase .k-sr-only para ocultar elementos de la vista sin quitárselos a los lectores de pantalla. También puedes crear tu propia clase CSS:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Otra opción muy útil es usar aria-describedby asociando la imagen al párrafo con su identificador:

<img src="./gianis.png" alt="Giannis Antetokounmpo Breaks Record" 
   aria-describedby="gianis-stats">
<p class="sr-only" id="gianis-stats">
    Giannis Antetokounmpo becomes the first player to
 have 45 points, 10 rebounds, 5 assists, and 0 turnovers
 in a game since Michael Jordan in 1989!
</p>

¡Listo! Ahora tenemos los datos del partido completamente accesibles sin romper el diseño visual.

Contraste del contenido

El contraste es otro punto crítico en nuestros sitios web. Muchas veces cuesta leer el texto porque el color de fondo y el de la tipografía no tienen suficiente diferencia.

A veces estás frente a una pantalla con poco brillo o en un lugar con mucha luz solar, por lo que debemos asegurar un buen nivel de contraste para que el contenido sea legible. Además, no todo el texto se mide igual: tenemos texto estándar y texto grande.

Chrome te ayuda a entender estas dificultades visuales permitiéndote simular deficiencias en la visión del color directamente desde DevTools.

¿Cómo debemos trabajar el contraste?

El texto estándar debe tener un contraste mínimo de 4.5:1. Para texto grande (18 puntos o más, o 14 puntos en negrita), el contraste mínimo requerido es de 3:1, lo que facilita su lectura.

Asimismo, los campos de formulario, botones e íconos deben cumplir con un contraste mínimo de 3:1. La única excepción son los elementos deshabilitados.

Aquí tienes herramientas prácticas para verificar el contraste de tus controles y enlaces:

Resumen

Vimos la diferencia entre imágenes decorativas y funcionales, cómo tratarlas y cómo lograr que los lectores de pantalla omitan imágenes decorativas usando propiedades CSS o atributos HTML como hidden y aria-hidden.

También revisamos técnicas para presentar grandes volúmenes de información sin romper el diseño usando aria-describedby, además de pautas para ofrecer un contraste adecuado ante deficiencias en la visión de colores.

Espero que esta información te sea de utilidad si estás dando tus primeros pasos en el mundo de la accesibilidad, igual que yo.

Parte de la serie Frontend

Modern frontend development — Angular, React, TypeScript, accessibility, and performance.

Ver serie completa

Artículos Relacionados

Compartir este artículo

Si esta guía te resultó útil, compártela con tu equipo o con otros desarrolladores.


Software real. Lecciones reales.

Comparto las lecciones que aprendí por las malas, para que puedas evitarlas o estar preparado cuando ocurran.

User avatar
User avatar
User avatar
User avatar
+13K

Únete a 13,800+ desarrolladores y lectores.

Cero spam. Cancela tu suscripción en cualquier momento.