Пользователь добавляет товар, выезжает красивая корзина-шторка — а человек, который пользуется клавиатурой или не видит экран, в этот момент теряется: фокус остался на странице, скринридер молчит, что вообще произошло — непонятно. Знакомо? Модальные окна и корзина-шторка красиво выглядят, но чаще всего именно они оказываются самыми недоступными местами магазина — и это прямая потеря заказов.
Эта статья — практический разбор того, как сделать модальные окна и корзину-шторку доступными на сайте на 1С-Битрикс: управление фокусом и фокус-ловушка, работа с клавиатуры, ARIA-роли, объявление изменений корзины скринридеру. Всё это — часть качественной проработки интерфейса, которую мы закладываем при аудите и оптимизации витрины.
Коротко
- Недоступная модалка или корзина-шторка — прямая потеря заказов у пользователей клавиатуры и скринридеров.
- Ключ к доступной модалке — управление фокусом: фокус-ловушка внутри и возврат на вызвавший элемент при закрытии.
- ARIA-роли и заголовок дополняют, но не заменяют правильное поведение клавиатуры (Tab, Escape).
- Изменения корзины объявляйте через ARIA live-области, чтобы скринридер озвучивал их без перехвата фокуса.
Почему доступность модалок — это про деньги
Доступность часто воспринимают как формальность «для галочки» или благотворительность. Для интернет-магазина это ошибка мышления: недоступный интерфейс напрямую отсекает часть покупателей. Люди, которые пользуются только клавиатурой, экранными дикторами или увеличением, — это реальная доля аудитории, и они тоже хотят покупать.
Модальные окна и корзина-шторка — критические точки этого пути. Через них проходит добавление в корзину, быстрый заказ, авторизация, оформление. Если хоть одно из этих окон не работает с клавиатуры или молчит для скринридера, пользователь не может завершить покупку — не потому что передумал, а потому что интерфейс его не пустил. Это тихая потеря конверсии, которую не видно в обычной аналитике, но она реальна.
Как ломается недоступная модалка
Чтобы понять, что чинить, полезно увидеть типичные поломки глазами пользователя клавиатуры или скринридера. Они повторяются от сайта к сайту.
- Фокус не переходит в окно. Модалка открылась визуально, но фокус остался на странице под ней.
- Фокус убегает наружу. Табуляция «проваливается» на скрытый за окном контент, пользователь теряется.
- Скринридер молчит. Нет роли и заголовка — диктор не сообщает, что открылось окно.
- Нельзя закрыть с клавиатуры. Escape не работает, а крестик — это div без роли кнопки.
- Фокус не возвращается. После закрытия фокус улетает в начало страницы, контекст потерян.
Обратите внимание: почти все поломки — про фокус и семантику, а не про внешний вид. Визуально окно может быть идеальным, но для клавиатуры и скринридера — полностью сломанным. Именно поэтому доступность нельзя оценить на глаз, только в реальном сценарии.
Управление фокусом и фокус-ловушка
Сердце доступного модального окна — правильное управление фокусом. Оно состоит из трёх обязательных моментов.
- Перенос фокуса внутрь. При открытии фокус ставится на окно — на заголовок, первый элемент или кнопку закрытия.
- Фокус-ловушка. Пока окно открыто, Tab и Shift+Tab ходят по кругу только внутри него, не уходя на страницу.
- Возврат фокуса. При закрытии фокус возвращается на элемент, который окно вызвал, — контекст сохраняется.
Фокус-ловушка (focus trap) — самый важный и самый часто забываемый элемент. Без неё пользователь клавиатуры, нажимая Tab, выходит за пределы окна на скрытый контент и не понимает, где он. Ловушка замыкает фокус в цикл: дошёл до последнего элемента — следующий Tab возвращает к первому. Плюс контент под окном помечают как недоступный, чтобы скринридер его не читал.
Клавиатура: Tab, Escape, Enter
Доступная модалка полностью управляется с клавиатуры — это базовое требование, потому что часть пользователей не работает мышью вообще. Набор ожидаемых клавиш стандартен, и его стоит соблюдать, а не изобретать своё.
- Tab / Shift+Tab. Перемещение по интерактивным элементам окна в пределах фокус-ловушки.
- Escape. Закрытие окна — ожидаемое и обязательное поведение.
- Enter / Space. Активация кнопок и элементов; кнопка должна быть настоящей кнопкой, а не div.
- Стрелки. Где уместно — навигация внутри списков, вкладок, счётчика количества.
Ключевой момент — интерактивные элементы должны быть семантическими: кнопки тегом button, поля тегом input. Тогда клавиатура работает сама собой. Когда «кнопка» сделана из div с обработчиком клика, она недоступна с клавиатуры, пока вручную не добавить роль, tabindex и обработку клавиш — и это почти всегда делают неполно.
ARIA-роли и заголовок окна
ARIA сообщает скринридеру, что за элемент перед пользователем. Для модального окна нужен небольшой, но обязательный набор атрибутов.
| Атрибут | Назначение |
|---|---|
| role="dialog" | Сообщает, что это модальное окно |
| aria-modal="true" | Контент под окном недоступен |
| aria-labelledby | Связывает окно с его заголовком |
| aria-label | Название окна, если нет видимого заголовка |
| role="alertdialog" | Для важных подтверждений и ошибок |
Важно понимать границы ARIA: она описывает элемент, но не заставляет его работать. Атрибут role="dialog" не переносит фокус и не ловит его — это делает код. Поэтому ARIA всегда идёт в паре с управлением фокусом и клавиатурой, а не вместо них. Частая ошибка — навесить роли и считать окно доступным, хотя фокус по-прежнему убегает наружу.
Специфика корзины-шторки
Корзина-шторка (выезжающая панель) — это по сути то же модальное окно, только сбоку, и к ней применимы те же правила: перенос фокуса внутрь, фокус-ловушка, закрытие по Escape, возврат фокуса. Но у неё есть своя специфика, которую легко упустить.
Во-первых, шторка часто открывается как реакция на добавление товара, а не по явному клику пользователя в неё. Значит, важно не только перенести фокус, но и не сбить человека с текущего действия — иногда фокус оставляют на месте, а факт добавления объявляют голосом (об этом ниже). Во-вторых, шторка содержит интерактив: изменение количества, удаление позиций, переход к оформлению. Каждый такой элемент должен быть доступной кнопкой или полем, а изменения суммы и состава — объявляться. Именно динамика корзины чаще всего и остаётся недоступной.
Объявление изменений корзины
Главная особенность корзины — она меняется динамически: добавили товар, изменили количество, обновилась сумма. Зрячий пользователь видит это, а незрячий — нет, если изменение не объявить. Для этого существуют ARIA live-области.
- aria-live="polite". Для обычных изменений: «Товар добавлен, в корзине 3 позиции» — озвучивается, не перебивая пользователя.
- aria-live="assertive". Для важного и ошибок: «Товар закончился» — озвучивается немедленно.
- Область заранее в DOM. Живая область должна существовать до сообщения, иначе оно может не прозвучать.
- Короткие сообщения. Скринридер читает текст целиком — формулировки делают ясными и краткими.
Такое объявление закрывает разрыв обратной связи: пользователь скринридера получает подтверждение действия так же, как зрячий видит анимацию корзины. Без live-областей добавление в корзину для незрячего происходит «в тишине», и он не уверен, сработало ли оно вообще.
Контраст, размеры и видимый фокус
Доступность — это не только клавиатура и скринридеры, но и визуальная часть, важная для слабовидящих и всех пользователей в неидеальных условиях.
- Контраст текста. Достаточный контраст с фоном, чтобы текст читался и при ярком свете, и при слабом зрении.
- Размер целей. Кнопки и элементы достаточно крупные, чтобы в них попадали и мышью, и пальцем.
- Видимый фокус. Элемент в фокусе явно выделен — без этого клавиатурный пользователь не понимает, где он.
- Не только цвет. Ошибки и статусы обозначаются не одним цветом, а ещё текстом или значком.
Особенно часто убирают видимый фокус (обводку) «ради красоты», не давая замены. Для пользователя клавиатуры это катастрофа: он перестаёт понимать, на каком элементе находится. Видимый фокус обязателен — его можно стилизовать под дизайн, но не удалять.
Доступность в компонентах 1С-Битрикс
Многие модальные окна и корзина-шторка на сайте строятся поверх штатных компонентов 1С-Битрикс — модуля «Интернет-магазин», оформления sale.order, всплывающих окон добавления в корзину. Готовые компоненты закрывают функциональность, но доступность в кастомных шаблонах и сторонних решениях часто оказывается неполной, и её приходится доводить.
Практический подход — не переписывать всё с нуля, а аккуратно дорабатывать шаблоны компонентов: добавлять роли и заголовки окнам, встраивать управление фокусом и live-области, заменять псевдокнопки на семантические. Такие доработки обычно оформляют аккуратно, чтобы они переживали обновления платформы, — как и любую кастомизацию. Принципы устойчивой доработки компонентов мы разбираем в статье про разработку своего модуля для Битрикс, а безопасный выкат таких правок — в материале про CI/CD и деплой на Битрикс.
Как тестировать доступность
Доступность нельзя проверить, глядя на экран, — только проходя сценарий как пользователь вспомогательных технологий. Минимальный, но обязательный набор проверок такой.
- Только клавиатура. Пройдите весь путь без мыши: открыть окно, перемещаться Tab, активировать Enter, закрыть Escape.
- Проверьте фокус. Убедитесь, что фокус переходит в окно, не убегает наружу и возвращается при закрытии.
- Включите скринридер. Понятно ли, какое окно открылось, озвучиваются ли изменения корзины.
- Автоматические проверки. Прогоните аудит доступности — он ловит часть проблем, но не все.
- Реальные условия. Проверьте контраст и видимый фокус, увеличение страницы, работу на телефоне.
Автоматические инструменты полезны, но они находят лишь формальные нарушения. Убегающий фокус, молчащую корзину и нелогичный порядок можно поймать только ручным проходом. Поэтому ручной тест с клавиатуры и скринридером — не опция, а обязательный этап.
Частые ошибки доступности
- Нет фокус-ловушки. Табуляция уходит на страницу под окном, пользователь теряется.
- Псевдокнопки из div. «Кнопки» и «крестик» без роли button недоступны с клавиатуры.
- Не работает Escape. Окно нельзя закрыть с клавиатуры, только мышью по крестику.
- Фокус не возвращается. После закрытия фокус улетает в начало страницы, контекст потерян.
- Молчит корзина. Изменения состава и суммы не объявляются через live-области.
- Убрали видимый фокус. Обводку удалили ради дизайна, клавиатурный пользователь не видит, где он.
- Только автотесты. Проверили инструментом и успокоились, ручной проход с клавиатуры не делали.
Чек-лист доступной модалки и корзины
- Фокус переходит внутрь. При открытии окна или шторки фокус ставится на них, а не остаётся на странице.
- Работает фокус-ловушка. Tab ходит по кругу внутри окна, контент под ним недоступен.
- Клавиатура полная. Tab, Escape, Enter работают; все элементы — семантические кнопки и поля.
- ARIA на месте. role="dialog", aria-modal и заголовок через aria-labelledby заданы.
- Возврат фокуса. При закрытии фокус возвращается на вызвавший элемент.
- Корзина объявляется. Изменения состава и суммы выводятся в ARIA live-область.
- Видимый фокус и контраст. Фокус явно выделен, текст контрастен, цели достаточно крупные.
- Проверено вручную. Сценарий пройден с клавиатуры и со скринридером, не только автотестом.
Вывод
Модальные окна и корзина-шторка выглядят эффектно, но именно они чаще всего оказываются самыми недоступными местами магазина. А поскольку через них идёт добавление в корзину, авторизация и оформление, их недоступность — это прямая, хоть и невидимая в обычной аналитике, потеря заказов у пользователей клавиатуры и скринридеров.
Хорошая новость: доступность здесь — это не про уродливый дизайн, а про правильную семантику и управление фокусом под красивой оболочкой. Настройте фокус-ловушку и возврат фокуса, сделайте элементы настоящими кнопками, добавьте ARIA-роли и объявление изменений корзины, сохраните видимый фокус — и окна станут доступными для всех, не потеряв ни во внешнем виде, ни в конверсии. А проверять это нужно руками, проходя сценарий с клавиатуры и скринридером, а не только автотестом.