Overlay — это визуальный слой, располагающийся поверх основного интерфейса и под активным интерактивным элементом (например, модальным окном). Он затемняет или размывает фоновый контент, тем самым выделяя активную область взаимодействия.
В системах, где используется библиотека focus-trap, overlay играет важную роль в создании корректного пользовательского опыта:
Хотя focus-trap отвечает исключительно за управление фокусом клавиатуры, визуальная часть интерфейса — overlay — реализуется с помощью CSS и HTML.
Overlay обычно располагается рядом с модальным контейнером и находится на том же уровне вложенности.
<div class="overlay"></div>
<div class="modal" role="dialog" aria-modal="true">
<button>Закрыть</button>
<input type="text" placeholder="Имя">
</div>
В типичной архитектуре:
.overlay — затемняющий слой.modal — интерактивная область, внутри которой работает
focus-trapПри активации модального окна:
Минимальная реализация overlay строится на фиксированном позиционировании.
.overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
Ключевые свойства:
| Свойство | Назначение |
|---|---|
position: fixed |
фиксирует слой относительно окна браузера |
inset: 0 |
растягивает overlay на весь экран |
background |
затемнение |
z-index |
управление уровнем наложения |
Overlay должен располагаться ниже модального окна, но выше основного контента.
.modal {
position: fixed;
z-index: 1001;
}
Overlay редко удаляется из DOM. Обычно он скрывается через CSS.
.overlay {
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease;
}
.overlay.active {
opacity: 1;
pointer-events: auto;
}
Преимущества подхода:
Overlay часто используется для блокировки взаимодействия с фоном.
Свойство pointer-events помогает управлять этим
поведением.
.overlay {
pointer-events: none;
}
.overlay.active {
pointer-events: auto;
}
Поведение:
| Состояние | Результат |
|---|---|
none |
клики проходят сквозь overlay |
auto |
overlay перехватывает клики |
В модальных интерфейсах активное состояние должно блокировать взаимодействие с фоновыми элементами.
Overlay часто используется вместе с техникой центрирования модального окна.
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Альтернативный подход — использование flex-контейнера.
.overlay {
display: flex;
align-items: center;
justify-content: center;
}
<div class="overlay">
<div class="modal">
...
</div>
</div>
Преимущества flex-подхода:
Плавное появление overlay улучшает восприятие интерфейса.
.overlay {
opacity: 0;
transition: opacity 200ms ease;
}
.overlay.active {
opacity: 1;
}
Часто анимация overlay синхронизируется с анимацией модального окна.
.modal {
transform: scale(0.95);
opacity: 0;
transition: transform 200ms ease, opacity 200ms ease;
}
.modal.active {
transform: scale(1);
opacity: 1;
}
Такое сочетание создаёт эффект «появления» диалога из центра экрана.
Современные интерфейсы иногда применяют размытие фона.
.overlay {
backdrop-filter: blur(6px);
background: rgba(0, 0, 0, 0.3);
}
Эффект:
Следует учитывать поддержку браузеров. В некоторых окружениях
backdrop-filter работает только с префиксом:
-webkit-backdrop-filter: blur(6px);
Overlay может иметь сложные эффекты затемнения.
.overlay {
background: radial-gradient(
circle at center,
rgba(0,0,0,0.3),
rgba(0,0,0,0.7)
);
}
Такой подход создаёт эффект более яркой центральной области.
Overlay часто используется как зона для закрытия модального окна.
overlay.addEventListener("click", () => {
modal.close();
});
Однако необходимо учитывать работу focus-trap.
При закрытии модального окна:
Пример:
trap.deactivate();
overlay.classList.remove("active");
Когда overlay активен, прокрутка страницы обычно блокируется.
Часто используется добавление класса на body.
body.modal-open {
overflow: hidden;
}
Jav * aScript:
document.body.classList.add("modal-open");
При закрытии:
document.body.classList.remove("modal-open");
Это предотвращает смещение интерфейса и прокрутку фонового контента.
В сложных интерфейсах может существовать несколько overlay.
Например:
Стек слоёв может выглядеть следующим образом:
z-index: 1000 overlay
z-index: 1001 modal
z-index: 1100 nested overlay
z-index: 1101 nested modal
Контроль иерархии слоёв предотвращает визуальные конфликты.
Overlay напрямую влияет на доступность интерфейса.
Основные правила:
Рекомендуется:
<div class="overlay" aria-hidden="true"></div>
Focus-trap обеспечивает, что клавиатурная навигация ограничена модальным контейнером.
Overlay должен корректно работать на мобильных устройствах.
Основные рекомендации:
inset: 0Пример:
.overlay {
padding: env(safe-area-inset-top)
env(safe-area-inset-right)
env(safe-area-inset-bottom)
env(safe-area-inset-left);
}
Это особенно важно для устройств с вырезами экрана.
Overlay может оказывать влияние на производительность при использовании сложных эффектов.
Потенциально затратные свойства:
backdrop-filterОптимизация:
Для большинства интерфейсов достаточно:
background: rgba(0,0,0,0.5);
В крупных приложениях overlay часто реализуется как переиспользуемый компонент.
Возможные архитектуры:
1. Глобальный overlay
Единственный элемент в корне приложения.
<body>
overlay-root
modal-root
</body>
Преимущества:
2. Локальный overlay
Каждый модальный компонент содержит собственный overlay.
modal
├ overlay
└ dialog
Преимущества:
Overlay перекрывает модальное окно
Причина — неправильный z-index.
Overlay не блокирует клики
Отсутствует pointer-events.
Фоновая прокрутка сохраняется
Не применяется overflow: hidden на
body.
Overlay получает фокус
Элемент не должен иметь tabindex.
Типичный сценарий:
import { createFocusTrap } from "focus-trap";
const modal = document.querySelector(".modal");
const overlay = document.querySelector(".overlay");
const trap = createFocusTrap(modal);
function openModal() {
overlay.classList.add("active");
modal.classList.add("active");
trap.activate();
}
function closeModal() {
overlay.classList.remove("active");
modal.classList.remove("active");
trap.deactivate();
}
Overlay обеспечивает визуальную изоляцию интерфейса, тогда как focus-trap ограничивает клавиатурную навигацию. Совместная работа этих механизмов формирует корректное поведение модальных интерфейсов.