label-in-name

Etiqueta en el nombre: el nombre accesible contiene el texto visible

automaticWCAG 2.5.3 (A)confianza: highgravedad: seriousoperable

Comprueba que, cuando un control tiene una etiqueta de texto visible, el nombre accesible contiene ese texto de la etiqueta visible.

Ámbito de aplicación. Se aplica a los controles nombrados mediante aria-label o aria-labelledby, que se renderizan visualmente y tienen texto de etiqueta visible que este motor puede extraer de forma determinista, ya sea de un <label> asociado, del propio texto renderizado del control, o de los elementos a los que apunta aria-labelledby. Los candidatos son <button>, <a href>, <summary>, los controles de formulario no ocultos, y los elementos cuyo atributo role se resuelve (su primer token conocido y no abstracto, sin distinguir mayúsculas de minúsculas) en el rol button, link, checkbox, radio, switch, searchbox, tab, menuitem, menuitemcheckbox, menuitemradio, option, treeitem o gridcell, y un <td> sin atributo role dentro de un grid o treegrid, que es un gridcell según HTML-AAM, excluyendo cualquiera que esté oculto o deshabilitado. Un <input> de tipo botón (submit, reset, button) con un value muestra ese valor como su etiqueta; sin él muestra el valor predeterminado del propio navegador, que no se puede conocer, y queda fuera del alcance. La etiqueta visible es el texto interior visible: el texto de los elementos en línea se une tal como está escrito (<b>Down</b>load se lee "Download"), una caja de bloque o un <br> inicia una palabra nueva, y el texto de una caja que nadie puede ver (recortada, de 1x1 px o totalmente transparente, como el texto solo para lectores de pantalla) se deja fuera, igual que las opciones de un <select> y el texto de un <textarea>, que son el valor de un campo, no texto de etiqueta. aria-hidden no se excluye: no cambia nada de lo que se renderiza en pantalla, que es de lo que trata este SC. Un aria-label que queda vacío tras recortar espacios, o un aria-labelledby cuyos ids no apuntan a nada o solo a elementos sin texto, no nombra nada: el nombre accesible sale entonces de la siguiente fuente (el contenido, un <label>, title...), como en un control sin ellos, así que el control queda fuera del alcance. Un elemento personalizado cuyos ElementInternals le dan uno de esos roles (this.attachInternals().role), sin un atributo role que nombre otro, cuenta como lo hace un elemento nativo con ese rol.

Resultado esperado. El nombre accesible contiene las palabras de la etiqueta visible, adyacentes y en orden. En un navegador, la etiqueta también se lee tal como se muestra: dos cajas dibujadas una junto a otra en una misma línea, sin espacio entre ellas, unen sus palabras (los elementos flex "sure" y "a11y" se leen "surea11y"), y un nombre que contiene cualquiera de las dos lecturas contiene la etiqueta. La comparación se hace por palabras, no por caracteres: el texto entre paréntesis se descarta, las mayúsculas y minúsculas se igualan, el texto se normaliza en NFKC, y cada carácter que no sea letra, dígito o marca combinante se convierte en separador, de modo que las diferencias de puntuación y espaciado nunca deciden el resultado. En cambio, los caracteres de formato invisibles (un guion blando, un espacio de ancho cero) y un apóstrofo dentro de una palabra se eliminan, de modo que "Down&shy;load" es "Download" y "Don’t" es "Dont". Los acentos no se igualan: "Déposer" sigue siendo una palabra, y un nombre que omite un acento ("Deposer") no la contiene. Cuatro casos que el marcado no puede resolver por sí solo devuelven cantTell en lugar de fail: una palabra separada por guion de forma distinta en los dos lugares; una palabra visible que el autor pudo haber abreviado, marcada por su punto final; texto visible renderizado mediante una fuente de iconos conocida (el texto del DOM son palabras reales, pero no se renderiza nada legible); y una etiqueta visible entera de exactamente un carácter que ni siquiera aparece dentro del nombre accesible, que según ACT 2ee8b8 puede ser "contenido no textual" (por ejemplo, "X" que significa "cerrar") en lugar de texto literal.

Qué informa un hallazgo.

  • visibleLabel, accessibleName: el texto de la etiqueta visible y el nombre accesible, tal como se encontraron.
  • normalized.visibleLabel, normalized.accessibleName: los mismos dos textos tal como se compararon: sin el texto entre paréntesis, sin distinguir mayúsculas y minúsculas, con normalización Unicode.
  • tokenized.visibleLabel, tokenized.accessibleName: las palabras en que se dividió cada texto, una palabra por elemento. El nombre debe contener las palabras de la etiqueta seguidas y en orden.
  • Cada texto se corta a los 2.000 caracteres, con "…" detrás, igual que el html de una ocurrencia, y cada lista de palabras en sus primeras 200 palabras.
  • labelSource: de dónde procede la etiqueta visible: label (un <label> asociado), self (el texto propio del control), value (el value de un <input> de tipo botón) o aria-labelledby (los elementos a los que apunta).
  • nameMechanism: qué da el nombre accesible: aria-label o aria-labelledby.

Estos campos de data.details ayudan a leer y reproducir un hallazgo. Salvo reasonCode y los pocos campos que Esquema de salida indica como estables, no son un contrato estable: un campo puede cambiar de nombre o desaparecer en una versión menor, así que no construyas sobre ellos.

Ejemplos

pass
<button aria-label="Save changes">Save</button>

El nombre accesible ("Save changes") contiene el texto visible ("Save").

fail
<button aria-label="Submit form">Save</button>

El nombre accesible no contiene el texto de la etiqueta visible.

Cómo comprobarlo

Cuando esta regla no puede decidir, informa cantTell y deja la pregunta a una persona. Cada pregunta que puede plantear aparece aquí bajo su código de motivo, con los pasos para responderla. Un hallazgo lleva los mismos pasos en howToCheck, en el idioma del análisis. Consulta Esquema de salida.

HYPHENATION_DIFFERS

  1. Leer la etiqueta visible del control que indica el informe.
  2. Abrir el panel Accesibilidad y leer el nombre accesible del control.
  3. Comparar ambos: solo difieren en la posición de los guiones («e-mail» frente a «email»); decidir si una persona que dijera la etiqueta visible pronunciaría las mismas palabras.
  4. Si dispone de software de entrada por voz, decir la etiqueta visible y ver si activa el control.

Se cumple. El nombre dice las mismas palabras que la etiqueta y solo difieren los guiones, así que al pronunciar la etiqueta se llega al control.

No se cumple. Los guiones cambian las palabras, así que el nombre no contiene lo que muestra la etiqueta, lo que incumple WCAG 2.5.3.

POSSIBLE_ABBREVIATION

  1. Leer la etiqueta visible del control que indica el informe y anotar la palabra que termina en punto.
  2. Abrir el panel Accesibilidad y leer el nombre accesible del control.
  3. Decidir si la palabra de la etiqueta es una abreviatura habitual de la palabra del nombre («Avda.» por «Avenida») que una persona leería en voz alta como la palabra completa.

Se cumple. La abreviatura es una convencional que se lee como la palabra completa contenida en el nombre.

No se cumple. La palabra de la etiqueta no se lee como la palabra del nombre, así que una persona que dijera la etiqueta no coincidiría con el nombre, lo que incumple WCAG 2.5.3.

POSSIBLE_ICON_FONT_GLYPH

  1. Observar en pantalla el control que indica el informe y anotar lo que muestra: palabras legibles o un icono.
  2. Abrir el panel Accesibilidad y leer el nombre accesible del control.
  3. Si el control solo muestra un icono, decidir si el nombre lo describe; si muestra palabras legibles, comprobar que el nombre las contiene.

Se cumple. El control muestra un icono en lugar de texto legible, o el texto legible que muestra está contenido en el nombre.

No se cumple. El control muestra palabras legibles que el nombre accesible no contiene, lo que incumple WCAG 2.5.3.

POSSIBLE_SYMBOLIC_CHARACTER

  1. Observar el carácter único que muestra el control que indica el informe.
  2. Abrir el panel Accesibilidad y leer el nombre accesible del control.
  3. Decidir si el carácter es un símbolo que representa una acción (una «X» para cerrar, una flecha) o un texto literal que el usuario pronunciaría, como una cifra o una letra.

Se cumple. El carácter es un símbolo, y el nombre describe lo que hace.

No se cumple. El carácter es un texto que el usuario pronunciaría (una cifra o una letra) y el nombre no lo contiene, lo que incumple WCAG 2.5.3.

Ver código fuente