ARIA-атрибуты

SortableJS — это мощная библиотека для создания интерактивных списков с возможностью перетаскивания элементов. Одним из ключевых аспектов профессиональной разработки является доступность интерфейса для пользователей с ограниченными возможностями. ARIA-атрибуты (Accessible Rich Internet Applications) позволяют сделать интерактивные компоненты более понятными для вспомогательных технологий, таких как экранные считыватели.


Поддержка доступности в SortableJS

SortableJS изначально предоставляет базовую поддержку ARIA, но правильная настройка атрибутов требует явного указания. В библиотеке применяются следующие ARIA-атрибуты для списков и элементов:

  • role="list" и role="listitem" Списку назначается роль list, а каждому элементу — listitem. Это позволяет вспомогательным технологиям корректно интерпретировать структуру списка.

  • aria-grabbed Атрибут указывает, захвачен ли элемент пользователем. Значение может быть:

    • "true" — элемент в данный момент перемещается,
    • "false" — элемент свободен для перемещения. SortableJS автоматически обновляет aria-grabbed при начале и завершении перетаскивания.
  • aria-dropeffect Определяет действие, которое произойдет при сбросе элемента на целевую область. Значения:

    • "move" — перемещение,
    • "copy" — копирование,
    • "none" — запрещено. Этот атрибут особенно полезен при работе с несколькими контейнерами, где элементы могут перемещаться между списками.

Настройка ARIA-атрибутов при инициализации

Для полного контроля над ARIA можно использовать параметр ariaId и события библиотеки. Пример конфигурации:

new Sortable(document.getElementById('myList'), {
    animation: 150,
    handle: '.drag-handle',
    ghostClass: 'sortable-ghost',
    onStart: function(evt) {
        evt.item.setAttribute('aria-grabbed', 'true');
    },
    onEnd: function(evt) {
        evt.item.setAttribute('aria-grabbed', 'false');
    }
});

В данном примере при начале перетаскивания элемент получает aria-grabbed="true", а после завершения — "false". Это позволяет экранным считывателям корректно отслеживать состояние перетаскивания.


Управление ARIA для контейнеров

Контейнеры, поддерживающие перетаскивание нескольких элементов, должны иметь явные роли и атрибуты для улучшенной доступности:

<ul id="sortableList" role="list" aria-dropeffect="move">
    <li role="listitem" tabindex="0">Элемент 1</li>
    <li role="listitem" tabindex="0">Элемент 2</li>
    <li role="listitem" tabindex="0">Элемент 3</li>
</ul>
  • tabindex="0" позволяет элементам быть фокусируемыми с клавиатуры, что важно для пользователей, работающих без мыши.
  • aria-dropeffect="move" сообщает, что элемент можно перемещать в пределах списка.

Динамическое обновление ARIA при сортировке

SortableJS предоставляет события onUpdate, onAdd и onRemove, которые можно использовать для динамического обновления ARIA-атрибутов:

onUpdate: function(evt) {
    let items = evt.from.querySelectorAll('[role="listitem"]');
    items.forEach((item, index) => {
        item.setAttribute('aria-posinset', index + 1);
        item.setAttribute('aria-setsize', items.length);
    });
}
  • aria-posinset указывает порядковый номер элемента в списке.
  • aria-setsize отражает общее количество элементов в списке. Эти атрибуты помогают экранным считывателям передавать точное положение каждого элемента.

ARIA и клавиатурное управление

Для полной доступности необходимо интегрировать поддержку клавиатуры. SortableJS не предоставляет встроенной поддержки клавиатурных операций, поэтому необходимо самостоятельно отслеживать события клавиш и обновлять ARIA:

list.addEventListener('keydown', function(evt) {
    let item = document.activeElement;
    if(evt.key === 'ArrowUp' && item.previousElementSibling) {
        item.parentNode.insertBefore(item, item.previousElementSibling);
    }
    if(evt.key === 'ArrowDown' && item.nextElementSibling) {
        item.parentNode.insertBefore(item.nextElementSibling, item.nextElementSibling.nextElementSibling);
    }
});

После перемещения элемента необходимо обновить aria-posinset и aria-setsize, чтобы сохранить синхронизацию с экранными считывателями.


Совместимость с другими технологиями доступности

Помимо стандартных ARIA-атрибутов, можно комбинировать SortableJS с другими библиотеками, поддерживающими доступность, например, для озвучивания динамических изменений через aria-live. Для списков с динамическими изменениями можно добавить контейнер с aria-live="polite", чтобы сообщать пользователю о перестановке элементов без прерывания текущей задачи.


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

  • Всегда назначать роли list и listitem для контейнера и элементов.
  • Обновлять aria-grabbed на каждом событии начала и конца перетаскивания.
  • Применять aria-dropeffect для указания действия при сбросе.
  • Поддерживать актуальные значения aria-posinset и aria-setsize после сортировки.
  • Обеспечить фокусируемость элементов через tabindex и обработку клавиш для полной клавиатурной навигации.

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