Современные браузеры строят внутреннее представление пользовательского интерфейса страницы, предназначенное для вспомогательных технологий — экранных дикторов, систем управления голосом, альтернативных устройств ввода. Это представление называется accessibility tree.
Accessibility tree не повторяет DOM-дерево полностью. В нём остаются только те узлы, которые имеют значение для доступности интерфейса. Каждый элемент получает:
Например, обычный HTML-элемент <button> в
accessibility tree будет представлен узлом с ролью button,
именем (полученным из текста или атрибутов) и возможными состояниями
вроде pressed.
В процессе разработки и автоматической проверки доступности возникает необходимость анализировать соответствие между HTML-разметкой и ожидаемыми ролями, описанными в спецификациях WAI-ARIA. Для решения этой задачи используется библиотека aria-query.
aria-query — это JavaScript-библиотека, содержащая структурированные данные о:
Она используется инструментами анализа доступности и линтерами (например, правилами eslint-plugin-jsx-a11y) для определения того, какой элемент должен появиться в accessibility tree и с какой ролью.
Главная особенность библиотеки — представление данных в виде Map-структур, позволяющих выполнять быстрые запросы:
При построении accessibility tree браузер использует:
aria-query моделирует эти правила в виде таблиц и словарей. Анализ accessibility tree через библиотеку обычно включает:
Таким образом, aria-query позволяет программно воспроизвести часть логики браузера при построении дерева доступности.
Библиотека экспортирует несколько основных наборов данных.
Коллекция ролей ARIA.
Каждая роль содержит:
widget, structure,
landmark)Пример структуры роли:
import { roles } from "aria-query";
const buttonRole = roles.get("button");
Объект роли содержит:
{
abstract: false,
accessibleNameRequired: true,
baseConcepts: [],
childrenPresentational: false,
props: {...},
requiredProps: {},
superClass: [...]
}
Эти данные используются при проверке корректности элементов интерфейса.
Коллекция соответствий HTML-элементов и ARIA-ролей.
Каждый ключ представляет описание HTML-элемента:
{
name: "button"
}
Значением является набор ролей, допустимых для этого элемента.
Пример запроса:
import { elementRoles } from "aria-query";
for (const [element, roles] of elementRoles) {
if (element.name === "button") {
console.log(roles);
}
}
Это позволяет определить:
Обратная структура данных — соответствие ролей и HTML-элементов.
import { roleElements } from "aria-query";
const buttonElements = roleElements.get("button");
Результатом будет список HTML-концептов, реализующих роль
button.
Эта структура активно используется анализаторами JSX-разметки для проверки правильности ролей.
Коллекция ARIA-атрибутов.
Каждый атрибут содержит описание:
Пример:
import { aria } from "aria-query";
const checked = aria.get("aria-checked");
Результат:
{
type: "tristate",
values: ["true", "false", "mixed"]
}
Это позволяет валидировать корректность значений ARIA-свойств.
Большинство HTML-элементов уже имеют встроенную семантику. Например:
| HTML элемент | implicit role |
|---|---|
| button | button |
| a[href] | link |
| nav | navigation |
| header | banner |
aria-query позволяет определить эту роль программно.
import { elementRoles } from "aria-query";
function getImplicitRoles(tagName) {
for (const [element, roles] of elementRoles) {
if (element.name === tagName) {
return [...roles];
}
}
}
Результат:
getImplicitRoles("button")
// Set { "button" }
Такая проверка используется в линтерах для выявления избыточных или ошибочных ролей.
ARIA позволяет разработчику явно задать роль:
<div role="button"></div>
Однако спецификация накладывает ограничения:
aria-query помогает определить допустимость роли.
import { roleElements } from "aria-query";
function isRoleSupported(role, element) {
const concepts = roleElements.get(role);
if (!concepts) return false;
for (const concept of concepts) {
if (concept.name === element) {
return true;
}
}
return false;
}
Такой анализ используется инструментами автоматической проверки доступности.
Не все ARIA-атрибуты могут применяться к любой роли. Например:
aria-checked допустим для checkboxaria-expanded используется для элементов с
раскрывающимся состояниемaria-query хранит информацию о том, какие свойства разрешены.
import { roles } from "aria-query";
const checkbox = roles.get("checkbox");
console.log(checkbox.props);
Результат — список допустимых ARIA-свойств.
Это позволяет автоматически проверять:
Некоторые ARIA-атрибуты можно применять ко всем элементам. Например:
aria-labelaria-labelledbyaria-describedbyaria-query помечает такие атрибуты как глобальные.
Пример проверки:
import { aria } from "aria-query";
function isGlobalAriaAttribute(name) {
const attr = aria.get(name);
return attr && attr.global;
}
Это важно при анализе accessibility tree, так как глобальные атрибуты участвуют в вычислении accessible name.
Одна из распространённых ошибок — конфликт между HTML-семантикой и ARIA-ролью.
Пример ошибки:
<button role="heading"></button>
Элемент button уже имеет роль button.
Переопределение её ролью heading нарушает правила
доступности.
aria-query позволяет обнаружить подобные ситуации.
Алгоритм проверки обычно включает:
Библиотека редко используется напрямую в прикладном коде интерфейсов. Основная область применения — инструменты анализа доступности.
Примеры:
Типичный процесс анализа:
В результате формируется набор предупреждений или ошибок доступности.
Несмотря на полезность библиотеки, она не заменяет полноценный движок построения accessibility tree.
Причины:
1. Отсутствие реального DOM-контекста
Браузеры учитывают:
aria-query не анализирует эти факторы.
2. Не рассчитывается accessible name
Формирование имени элемента зависит от сложного алгоритма:
aria-labelledbyaria-labelaria-query предоставляет только данные о свойствах.
3. Нет обработки состояния интерфейса
Например:
expandedselectedpressedЭти состояния должны анализироваться отдельно.
При создании собственного анализатора доступности aria-query используется как база знаний.
Типичный алгоритм:
Результатом становится модель узла accessibility tree:
Node
├ role
├ accessible name
├ states
├ properties
└ relationships
aria-query покрывает шаги, связанные с ролями и свойствами.
Библиотека играет важную роль в экосистеме инструментов доступности Jav * aScript:
Использование aria-query делает возможным программный анализ семантики интерфейса и приближает инструменты разработки к логике построения настоящего accessibility tree, используемого браузерами и вспомогательными технологиями.