Путаница с устаревшими атрибутами

В экосистеме веб-доступности значительная часть проблем связана не с отсутствием ARIA-атрибутов, а с их неправильным применением. Со временем спецификация WAI-ARIA развивается: появляются новые роли, уточняется поведение атрибутов, некоторые свойства объявляются устаревшими или заменяются более точными механизмами. В результате в кодовых базах часто сохраняются атрибуты, которые больше не соответствуют актуальной модели доступности.

Библиотека aria-query служит инструментом для анализа и сопоставления ролей, свойств и состояний ARIA. Она используется во многих инструментах статического анализа, включая линтеры доступности. Одной из её задач является выявление несоответствий между ролью элемента и применяемыми к нему атрибутами, включая устаревшие или недопустимые свойства.

Понимание того, как библиотека определяет допустимость атрибутов, позволяет избежать распространённой путаницы при работе с ARIA.


Природа устаревания ARIA-атрибутов

ARIA-атрибут может считаться устаревшим по нескольким причинам:

  • атрибут исключён из актуальной версии спецификации;
  • атрибут заменён более точным свойством;
  • атрибут больше не имеет смысла в контексте современных ролей;
  • его поведение стандартизировано иначе.

В спецификациях WAI-ARIA используется несколько терминов:

Статус Значение
Deprecated атрибут сохраняется для обратной совместимости, но использовать его не рекомендуется
Obsolete атрибут больше не должен применяться
Discouraged формально допустим, но существуют более корректные решения

Инструменты, основанные на aria-query, используют актуальные таблицы соответствия ролей и свойств. Это позволяет автоматически обнаруживать ситуации, когда атрибут больше не считается корректным.


Роль aria-query в анализе атрибутов

Библиотека представляет спецификацию ARIA в виде структурированных наборов данных. Среди ключевых структур:

  • roles — карта ролей ARIA;
  • ariaProps — перечень всех ARIA-атрибутов;
  • elementRoles — соответствие HTML-элементов ролям;
  • roleElements — обратная карта.

Каждая роль содержит информацию:

  • разрешённые свойства;
  • обязательные свойства;
  • наследуемые свойства;
  • запрещённые состояния.

Пример получения списка всех ARIA-атрибутов:

import { aria } from "aria-query";

for (const [name, definition] of aria.entries()) {
  console.log(name, definition);
}

Объект definition содержит метаданные:

  • тип значения;
  • допустимые значения;
  • состояние устаревания;
  • категории использования.

Это позволяет инструментам анализа проверять не только наличие атрибута, но и его актуальность.


Пример обнаружения устаревшего атрибута

Рассмотрим элемент:

<div role="treeitem" aria-grabbed="true"></div>

Атрибут aria-grabbed использовался в ранних версиях ARIA для реализации drag-and-drop. В современных версиях спецификации этот атрибут признан устаревшим.

С помощью aria-query можно проверить статус свойства:

import { aria } from "aria-query";

const grabbed = aria.get("aria-grabbed");

console.log(grabbed.deprecated);

Результат:

true

Такая информация используется линтерами для генерации предупреждений.


Распространённые устаревшие ARIA-атрибуты

Некоторые свойства чаще других встречаются в устаревшем коде.

aria-grabbed

Использовался для указания, что элемент находится в состоянии перетаскивания.

Причина устаревания:

  • современные браузеры используют HTML Drag and Drop API
  • ARIA-модель была пересмотрена

Старый код:

<div draggable="true" aria-grabbed="true"></div>

Корректная практика:

<div draggable="true"></div>

ARIA больше не требуется.


aria-dropeffect

Ранее описывал тип возможного действия при drop.

Пример устаревшего использования:

<div aria-dropeffect="move"></div>

Причина устаревания:

  • поведение drag-and-drop определяется скриптами
  • атрибут не влиял на доступность в большинстве технологий чтения экрана

Как aria-query отражает устаревшие свойства

Внутренние данные библиотеки включают признак deprecated.

Структура описания свойства:

{
  type: "boolean",
  values: ["true", "false"],
  deprecated: true
}

Инструмент проверки может анализировать DOM и сверять атрибуты:

  1. получить список атрибутов элемента
  2. проверить наличие в ariaProps
  3. проверить флаг deprecated

Пример простой проверки:

import { aria } from "aria-query";

function isDeprecated(attr) {
  const prop = aria.get(attr);
  return prop && prop.deprecated === true;
}

Использование:

isDeprecated("aria-grabbed"); 

Путаница между устаревшими и недопустимыми атрибутами

Важно различать две разные категории ошибок.

Недопустимый атрибут

Свойство не разрешено для роли.

Пример:

<button aria-level="2"></button>

Атрибут aria-level предназначен для ролей:

  • heading
  • treeitem
  • listitem

Но не для button.

Устаревший атрибут

Свойство существовало, но больше не рекомендуется.

Пример:

<div aria-grabbed="true"></div>

В этом случае атрибут формально распознаётся, но считается устаревшим.

Библиотека aria-query различает эти случаи:

  • проверка допустимости через roles
  • проверка устаревания через ariaProps

Проверка атрибутов относительно роли

Информация о разрешённых свойствах хранится внутри описания роли.

Пример:

import { roles } from "aria-query";

const buttonRole = roles.get("button");

console.log(buttonRole.props);

Результат:

{
  "aria-expanded": null,
  "aria-pressed": null,
  ...
}

Алгоритм проверки:

  1. определить роль элемента
  2. получить список разрешённых свойств роли
  3. сравнить с атрибутами DOM

Если атрибут отсутствует в списке — ошибка совместимости.


Наследуемые свойства ролей

ARIA использует механизм наследования ролей.

Например:

widget
 └── button

Если атрибут разрешён в widget, он автоматически допустим и в button.

В aria-query это отражается через поле superClass.

Пример:

const role = roles.get("button");

console.log(role.superClass);

Результат:

[["roletype","widget","command"]]

Проверка атрибутов должна учитывать:

  • собственные свойства роли
  • свойства родительских ролей

Исторические причины появления устаревших атрибутов

Некоторые ARIA-атрибуты появились в период активного развития доступности веба, когда спецификация ещё не была стабильной.

Наиболее характерные причины:

1. Попытка описать сложное взаимодействие

Drag-and-drop изначально требовал описания состояния перетаскивания.

2. Ограничения ранних скринридеров

Некоторые атрибуты вводились для компенсации недостатков старых технологий чтения.

3. Перекрытие с HTML-семантикой

По мере развития HTML многие функции стали нативными.


Устаревшие атрибуты в старых фреймворках

Код, написанный 8–10 лет назад, часто содержит устаревшие ARIA-паттерны.

Особенно это характерно для:

  • ранних версий Angular
  • старых React-компонентов
  • библиотек UI до появления современных accessibility-гайдов

Пример старого drag-and-drop:

<li aria-grabbed="false"></li>
<li aria-grabbed="true"></li>

Современные реализации используют:

  • pointer events
  • HTML drag API
  • JavaScript-состояние

ARIA-атрибуты в таких случаях не применяются.


Использование aria-query в линтерах

Наиболее известные инструменты используют aria-query как источник спецификации:

  • eslint-plugin-jsx-a11y
  • accessibility-валидаторы
  • тестовые фреймворки

Типичный процесс проверки:

  1. анализ AST JSX или HTML
  2. извлечение ARIA-атрибутов
  3. сопоставление с данными aria-query
  4. генерация предупреждений

Пример логики линтера:

if (isDeprecated(attribute)) {
  context.report({
    message: "ARIA attribute is deprecated"
  });
}

Ошибки интерпретации устаревания

Некоторые разработчики ошибочно удаляют ARIA-атрибуты, не проверив их статус.

Типичные проблемы:

Удаление необходимых атрибутов

Например:

aria-expanded
aria-controls
aria-labelledby

Эти свойства активно используются и не являются устаревшими.

Путаница с экспериментальными атрибутами

Некоторые свойства находятся на стадии обсуждения и отсутствуют в aria-query. Это не означает, что они устарели.


Проверка соответствия спецификации

Для надёжной проверки используется несколько уровней анализа.

1. Наличие свойства

aria.has("aria-expanded")

2. Статус устаревания

aria.get("aria-expanded").deprecated

3. Совместимость с ролью

roles.get(role).props

Комбинация этих проверок позволяет точно определить:

  • допустимость
  • актуальность
  • корректность применения

Практическая ценность данных aria-query

Использование библиотеки обеспечивает:

  • синхронизацию с актуальной спецификацией ARIA
  • единый источник правды для инструментов анализа
  • автоматическое выявление устаревших практик
  • улучшение доступности интерфейсов

Особенно важным становится автоматическое обнаружение устаревших атрибутов в крупных проектах, где ручная проверка невозможна.

В результате aria-query выступает не только справочной базой данных ARIA, но и фундаментом для систем статической проверки доступности в современном JavaScript-экосистеме.