Saltar al contenido

El patrón correcto para iconos

Los cinco casos de icono en una interfaz, dónde va el nombre accesible en cada uno, el tamaño mínimo del objetivo táctil, y el contraste que exige un icono que porta información.

Caso 1: icono junto a texto

El más frecuente y el más simple.

HTML
<button type="button" class="boton">  <svg aria-hidden="true" width="16" height="16"><use href="#i-guardar" /></svg>  Guardar</button>

El icono se oculta. El nombre del botón sale de su contenido de texto. Nada más que hacer.

Lo mismo para un enlace, un elemento de lista, una fila de tabla o un encabezado con icono. Si hay texto al lado que dice lo mismo, el icono es decorativo.

Caso 2: icono solo, en un control

Un botón sin texto. El nombre va en el control, no en el icono.

HTML
<button type="button" class="boton-icono" aria-label="Cerrar el diálogo">  <svg aria-hidden="true" width="20" height="20"><use href="#i-cruz" /></svg></button>

Por qué en el control y no en el SVG: porque el nombre describe la acción, no el dibujo. «Cerrar el diálogo» es lo que hace el botón; «cruz» es lo que se ve. Y porque el cálculo del nombre accesible de un button con aria-label tiene el soporte más sólido que existe.

Una alternativa igualmente válida y a veces mejor:

HTML
<button type="button" class="boton-icono">  <svg aria-hidden="true" width="20" height="20"><use href="#i-cruz" /></svg>  <span class="solo-lector">Cerrar el diálogo</span></button>

Es más verboso y tiene dos ventajas: el texto se traduce como contenido, y si el CSS falla, el usuario ve la palabra en lugar de un botón vacío.

Caso 3: icono solo, portando información

Un icono de estado en una tabla, sin control alrededor. No hay dónde poner el nombre salvo en el propio SVG o en un texto oculto.

HTML
<td>  <svg aria-hidden="true" width="16" height="16" class="ico-ok"><use href="#i-check" /></svg>  <span class="solo-lector">Pagado</span></td>

Aquí hay una segunda obligación que la mayoría pasa por alto: el color no puede ser el único portador del significado. Si el estado se distingue solo por un tic verde frente a una cruz roja, quien no percibe ese contraste de color pierde la información. La forma tiene que ser distinta, no solo el color, y en este caso lo es. Si tu diseño usa el mismo símbolo en dos colores, tienes un problema que ningún atributo ARIA arregla.

Caso 4: icono decorativo puro

Un adorno, una flecha de acompañamiento, una ilustración de fondo.

HTML
<svg aria-hidden="true" width="120" height="80"><use href="#ilustracion-vacio" /></svg>

Nada más. Y si es un fondo, mejor todavía en CSS con background-image o mask, donde ni siquiera está en el DOM.

Caso 5: icono que es un enlace

Un logotipo que enlaza a la portada, o un icono de red social.

HTML
<a href="/" class="logo">  <svg aria-hidden="true" width="120" height="32"><use href="#logotipo" /></svg>  <span class="solo-lector">Inicio</span></a>

El nombre describe el destino, no el dibujo. Y aquí es especialmente importante que el texto sea informativo: una lista de enlaces de redes sociales donde todos se llaman «icono» es inservible en la navegación por enlaces de un lector de pantalla, que presenta la lista de nombres fuera de contexto.

La tabla

Caso aria-hidden en el SVG Dónde va el nombre
Icono junto a texto Sí Ya está en el texto
Icono solo en un control Sí En el control
Icono solo con información Sí Texto oculto al lado
Icono decorativo Sí En ningún sitio
Icono como enlace Sí En el enlace

La columna del medio tiene el mismo valor en las cinco filas. Esa es la conclusión operativa del artículo: el componente de icono debe llevar aria-hidden="true" por defecto, siempre, y el nombre se resuelve fuera.

Tamaño y contraste

Dos requisitos que no son de marcado y que fallan igual de a menudo.

El objetivo táctil. Un icono de 16 píxeles dentro de un botón sin relleno es un objetivo de 16 por 16. Las pautas de accesibilidad establecen un mínimo de 24 por 24 píxeles CSS para los objetivos de puntero, con excepciones cuando hay separación suficiente entre objetivos. El criterio más exigente de nivel AAA pide 44 por 44. En la práctica: el botón, no el icono, debe medir al menos 24 píxeles, y 44 en una interfaz táctil.

CSS
.boton-icono {  display: inline-grid;  place-items: center;  inline-size: 2.75rem;   /* 44px */  block-size: 2.75rem;}

El contraste. Un icono que porta información es un objeto gráfico esencial para la comprensión, y las pautas exigen una relación de contraste de al menos 3 a 1 con lo que tenga alrededor. Un icono gris claro sobre fondo blanco falla, aunque se vea «bien» en la pantalla del diseñador.

Y un matiz que se olvida: el contraste se mide sobre la parte más fina del icono. Un icono de trazo de 1,5 unidades con antialiasing tiene, en la práctica, un contraste efectivo menor que el que calcula la herramienta sobre el color plano. En iconos de línea conviene subir el grosor antes que el contraste.