Ловушка фокуса внутри lightbox

Одной из важнейших особенностей веб-разработки является обеспечение доступности контента для всех пользователей, включая тех, кто использует клавиатуру или специализированные устройства для навигации. В контексте модальных окон, таких как lightbox, особое внимание следует уделить правильному управлению фокусом, чтобы избежать ситуаций, когда пользователь оказывается “пойман” в модальном окне без возможности вернуться к остальной части страницы.

Библиотека BasicLightbox предоставляет простое решение для реализации модальных окон, но она не всегда учитывает все нюансы доступности, включая управление фокусом. Важно, чтобы при открытии модального окна фокус перемещался внутрь него и оставался там до тех пор, пока окно не будет закрыто. Также после закрытия окна фокус должен возвращаться на тот элемент, который вызвал окно.

Проблема фокуса

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

Особенно важно правильно управлять фокусом при:

  1. Открытии lightbox — фокус должен быть на первом интерактивном элементе внутри окна, будь то кнопка “Закрыть”, изображение или форма.
  2. Навигации внутри lightbox — фокус не должен выходить за пределы модального окна. При использовании клавиши Tab пользователь должен перемещаться только внутри lightbox.
  3. Закрытии lightbox — фокус должен возвращаться на элемент, который вызвал открытие модального окна.

Управление фокусом при открытии lightbox

Для корректного управления фокусом важно, чтобы при открытии lightbox фокус перемещался на первый интерактивный элемент внутри модального окна. Библиотека BasicLightbox не предоставляет встроенной функции для этого, но с помощью небольшого количества JavaScript можно решить эту задачу.

После открытия модального окна можно вручную установить фокус на первый элемент внутри lightbox. Это можно сделать с помощью метода focus().

Пример:

const instance = basicLightbox.create(`
  <div>
    <button id="close">Закрыть</button>
    <img src="image.jpg" alt="Изображение">
  </div>
`);

instance.show();

// Устанавливаем фокус на кнопку закрытия
document.getElementById('close').focus();

В этом примере, при открытии lightbox фокус устанавливается на кнопку “Закрыть”. Это обеспечивает, что пользователь с клавиатурной навигацией сразу попадет на интерактивный элемент.

Ловушка фокуса внутри lightbox

Когда пользователь использует клавишу Tab для навигации, важно, чтобы фокус не выходил за пределы модального окна. Это называется “ловушка фокуса”. Чтобы добиться этого, нужно перехватывать действия с клавишами и перенаправлять фокус на первый или последний элемент в окне.

Пример реализации ловушки фокуса:

const instance = basicLightbox.create(`
  <div role="dialog" aria-labelledby="lightboxTitle">
    <h2 id="lightboxTitle">Описание изображения</h2>
    <button id="close">Закрыть</button>
    <img src="image.jpg" alt="Изображение">
  </div>
`);

instance.show();

const focusableElements = document.querySelectorAll(
  '#close, img, button'
);
const firstFocusableElement = focusableElements[0];
const lastFocusableElement = focusableElements[focusableElements.length - 1];

document.addEventListener('keydown', function(e) {
  if (e.key === 'Tab') {
    if (e.shiftKey) { // Shift + Tab
      if (document.activeElement === firstFocusableElement) {
        lastFocusableElement.focus();
        e.preventDefault();
      }
    } else { // Tab
      if (document.activeElement === lastFocusableElement) {
        firstFocusableElement.focus();
        e.preventDefault();
      }
    }
  }
});

В этом примере при нажатии клавиши Tab фокус будет перемещаться между элементами внутри lightbox, не выходя за его пределы. Если пользователь достигнет последнего элемента, нажатие Tab перенаправит фокус на первый элемент. Аналогично, если пользователь использует Shift + Tab, фокус будет перемещаться в обратном порядке, и при достижении первого элемента фокус вернется на последний.

Возвращение фокуса после закрытия lightbox

При закрытии lightbox фокус должен вернуться на элемент, который его вызвал. В случае с библиотекой BasicLightbox это можно реализовать, сохраняя ссылку на элемент перед открытием модального окна.

Пример:

const triggerElement = document.getElementById('trigger');
const instance = basicLightbox.create(`
  <div>
    <button id="close">Закрыть</button>
    <img src="image.jpg" alt="Изображение">
  </div>
`, {
  onClose: () => {
    triggerElement.focus(); // Возвращаем фокус на элемент, который вызвал окно
  }
});

triggerElement.addEventListener('click', () => {
  instance.show();
});

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

Заключение

Правильное управление фокусом в lightbox не только улучшает доступность веб-страницы, но и создает более удобный опыт для пользователей, особенно для тех, кто использует клавиатуру для навигации. Простые техники, такие как установка фокуса на первый интерактивный элемент при открытии окна и создание ловушки фокуса, помогают обеспечить, чтобы пользователь не выходил за пределы модального окна.