Screen reader поддержка

Muuri — это библиотека для создания интерактивных сеток с динамическим расположением элементов и возможностью перетаскивания. Одним из критических аспектов доступности современных интерфейсов является поддержка screen reader-ов (программ для чтения с экрана). Muuri предоставляет базовые инструменты для интеграции с такими технологиями, однако правильная организация DOM и управление ARIA-атрибутами остаются за разработчиком.


Основы доступности сетки

Элементы сетки Muuri изначально являются обычными DOM-элементами, что делает их доступными для большинства скринридеров. Важно учитывать следующие моменты:

  • Семантические теги: Использование <ul> и <li> для списков или <div role="grid"> и <div role="gridcell"> для сеток с ячейками позволяет screen reader-у корректно идентифицировать структуру.
  • Фокусируемые элементы: Любой интерактивный элемент сетки (кнопка, ссылка, draggable item) должен иметь атрибут tabindex="0" или соответствующую семантическую роль, чтобы пользователь мог навигировать с клавиатуры.
  • ARIA-атрибуты: Поддержка атрибутов aria-label, aria-labelledby и aria-describedby позволяет дать скринридеру описания элементов сетки и их состояния.

Управление фокусом при drag-and-drop

Muuri поддерживает перетаскивание элементов, что может создавать сложности для пользователей screen reader-ов. Основные практики:

  1. Фокус после drag: После завершения перетаскивания необходимо программно вернуть фокус на перемещённый элемент. Это предотвращает потерю ориентации для пользователей с ограниченной видимостью.

    grid.on('move', function (item) {
      item.getElement().focus();
    });
  2. ARIA-live уведомления: Использование контейнеров с aria-live="polite" позволяет сообщать о перемещении элементов. Например, при смене позиции элемента можно обновлять текст в скрытом элементе:

    <div id="sr-status" aria-live="polite" style="position:absolute; left:-9999px;"></div>
    grid.on('move', function(item) {
      document.getElementById('sr-status').textContent = `Элемент "${item.getElement().textContent}" перемещён.`;
    });
  3. Клавиатурное управление drag: Для полного соответствия доступности важно реализовать альтернативу drag-and-drop с клавиатуры. Например, перемещение элементов с помощью стрелок и клавиши Enter/Space:

    item.getElement().addEventListener('keydown', function(e) {
      if (e.key === 'ArrowUp') { grid.move(item, item.getIndex() - 1); }
      if (e.key === 'ArrowDown') { grid.move(item, item.getIndex() + 1); }
    });

Поддержка динамического контента

Muuri позволяет добавлять и удалять элементы в реальном времени. Для screen reader-ов важно уведомлять о таких изменениях:

  • ARIA-live регионы: Создание одного или нескольких live-областей для уведомления о добавлении или удалении элементов.

    grid.on('add', function(items) {
      items.forEach(item => {
        document.getElementById('sr-status').textContent = `Добавлен элемент "${item.getElement().textContent}".`;
      });
    });
  • Обновление tabindex: Любой новый элемент должен быть доступен через клавиатуру (tabindex="0"). Элементы, которые больше не нужны, должны быть удалены из таб-индекса.


Использование ролей ARIA в сетке

Для сложных интерфейсов с Muuri рекомендуется явное определение ролей:

  • Сетка: role="grid" или role="list"
  • Ячейки: role="gridcell" или role="listitem"
  • Перетаскиваемый элемент: aria-grabbed="true|false" для информирования о состоянии drag
  • Уведомления о перемещении: aria-live="polite" или aria-live="assertive" в зависимости от критичности события

Пример структуры:

<div role="grid" aria-label="Список задач">
  <div role="gridcell" tabindex="0" aria-grabbed="false">Задача 1</div>
  <div role="gridcell" tabindex="0" aria-grabbed="false">Задача 2</div>
</div>
<div id="sr-status" aria-live="polite" style="position:absolute; left:-9999px;"></div>

Итоговые рекомендации

  • Всегда обеспечивать фокус на интерактивных элементах после любых действий.
  • Использовать ARIA-live для динамических событий, таких как добавление, удаление и перемещение элементов.
  • Обеспечивать альтернативное управление с клавиатуры для drag-and-drop.
  • Чётко определять семантические роли элементов сетки для корректного восприятия screen reader-ами.
  • Поддерживать правильный порядок в DOM, так как скринридеры читают элементы по порядку, а Muuri меняет визуальное положение без изменения порядка в DOM, поэтому уведомления через live-region критически важны.

Эти подходы делают сетки Muuri доступными и удобными для пользователей с ограничениями по зрению, сохраняя интерактивность и динамичность интерфейса.