Библиотека Shopify Draggable предоставляет мощный инструмент для реализации перетаскивания элементов на веб-страницах. Одним из ключевых аспектов доступности является корректная работа с экранными считывателями (screen readers), что позволяет пользователям с ограничениями зрения взаимодействовать с интерфейсом.
При работе с перетаскиваемыми элементами важно соблюдать несколько принципов:
Фокус и порядок табуляции Перетаскиваемые
элементы должны оставаться доступными через клавиатуру. Это достигается
использованием атрибутов tabindex="0" для элементов,
которые могут быть перемещены, чтобы экранные считыватели и клавиатурная
навигация распознавали их как интерактивные.
ARIA-атрибуты Для передачи информации о состоянии перетаскивания используются ARIA-атрибуты:
aria-grabbed="true/false" — указывает, что элемент
выбран для перетаскивания.aria-dropeffect="move" — обозначает возможное действие
при отпускании элемента.role="list" и role="listitem" — помогают
структурировать контейнеры и элементы для правильного чтения
списков.Динамическое уведомление о действиях Экранные
считыватели не могут автоматически отслеживать визуальные изменения DOM.
Необходимо использовать aria-live или специальные события
для информирования о начале и окончании перетаскивания:
<div id="live-region" aria-live="polite" style="position:absolute; left:-9999px;"></div>
При начале перетаскивания:
document.getElementById('live-region').textContent = 'Элемент выбран для перемещения';
При завершении:
document.getElementById('live-region').textContent = 'Элемент перемещен на новое место';При создании Draggable необходимо явно указывать селекторы, к которым будет применяться функциональность, а также слушать события для обновления состояния ARIA:
import { Draggable } from '@shopify/draggable';
const container = document.querySelector('.draggable-container');
const draggable = new Draggable(container, {
draggable: '.draggable-item',
delay: 150,
mirror: {
constrainDimensions: true
}
});
// Обработка событий для экранных считывателей
draggable.on('drag:start', (evt) => {
evt.source.setAttribute('aria-grabbed', 'true');
document.getElementById('live-region').textContent = `Элемент ${evt.source.textContent} выбран для перемещения`;
});
draggable.on('drag:stop', (evt) => {
evt.source.setAttribute('aria-grabbed', 'false');
document.getElementById('live-region').textContent = `Элемент ${evt.source.textContent} перемещен`;
});
Особенности реализации:
drag:start и drag:stop позволяют
синхронизировать ARIA-состояния с действиями пользователя.mirror используется для визуальной репрезентации
перетаскиваемого объекта, не влияя на сам DOM элемент, что предотвращает
неожиданные изменения для screen readers.Для пользователей, которые не используют мышь, Draggable предоставляет базовую поддержку клавиатуры через расширения или кастомные обработчики:
Tab и стрелок.Enter или
Space.aria-live.Пример обработки клавиатурного перемещения:
container.addEventListener('keydown', (evt) => {
const active = document.activeElement;
if (!active.classList.contains('draggable-item')) return;
switch(evt.key) {
case 'ArrowUp':
container.insertBefore(active, active.previousElementSibling);
break;
case 'ArrowDown':
container.insertBefore(active.nextElementSibling, active);
break;
}
document.getElementById('live-region').textContent = `Элемент ${active.textContent} перемещен с клавиатуры`;
});
Tab,
Shift+Tab и стрелки.mirror) не создают
лишних дублей для считывателей.role и
aria-dropeffect.Эффективная интеграция Shopify Draggable с экранными считывателями повышает общую доступность интерфейса, делая динамические элементы доступными для всех пользователей.