Popover API можно освоить на одном небольшом проекте, если сразу видеть вход, действие и результат. Нативные атрибуты popover и popovertarget связывают кнопку с всплывающим слоем без ручного переключения display. Ниже вы соберёте работающий пример и проверите обычный и граничный сценарии.
Самодельное меню легко забывает про Escape, фокус, клик снаружи и слой поверх остального интерфейса. Поэтому отделим настройку, входные данные, основное действие и проверку. В этой статье вы соберёте меню профиля с light dismiss и отдельную подсказку, которые открываются нативной кнопкой и аккуратно анимируются. Проверка: кнопка открывает меню, Escape и клик снаружи закрывают его, Tab проходит по ссылкам, а страница работает без отдельной библиотеки.
добавить popovertarget кнопке и совпадающий id элементу. Не расширяйте проект до первого успешного запуска.
Escape и клик снаружи закрывают меню. Проверяйте значение, а не отсутствие ошибки.
После успеха добавьте подсказку manual и кнопку, которая закрывает её через popovertargetaction. Так копирование станет практикой.
Как устроен учебный проект Popover API
Кнопка declaratively указывает id popover, браузер управляет верхним слоем и состоянием открытия, а CSS оформляет :popover-open и backdrop. Держите ввод, логику и отображение раздельно: тогда каждый этап можно проверить отдельно.
| Этап | Действие | Проверяемый результат |
|---|---|---|
| Связь | добавить popovertarget кнопке и совпадающий id элементу | клик открывает и закрывает popover |
| Поведение | выбрать auto для light dismiss | Escape и клик снаружи закрывают меню |
| Стили | оформить :popover-open, ::backdrop и переход | слой появляется без скачка layout |
| Клавиатура | пройти меню Tab и Shift+Tab | ссылки доступны, а фокус не теряется |
Контрольные точки: связь, поведение, стили и клавиатура. Следующий шаг начинается после совпадения с ожидаемым результатом.

От входных данных до видимого результата. Сначала проверяется вход, затем действие и только потом интерфейс.
Собираем рабочий пример шаг за шагом
Пример сверялся с актуальной документацией MDN Popover API на 19 октября 2026 года. Создайте простой HTML-файл и откройте через локальный сервер. Для базового popover сборщик и зависимости не нужны. Проверьте текущую папку через pwd или Get-Location. Вставьте пример целиком, выполните один раз, затем разбирайте по частям.
<button type="button" popovertarget="profile-menu">
Открыть профиль
</button>
<nav id="profile-menu" popover="auto" aria-label="Меню профиля">
<a href="/profile">Мой профиль</a>
<a href="/settings">Настройки</a>
<button type="button" popovertarget="profile-menu" popovertargetaction="hide">
Закрыть
</button>
</nav>
<style>
#profile-menu {
border: 0;
border-radius: 16px;
padding: 16px;
box-shadow: 0 20px 60px #18203d33;
opacity: 0;
transform: translateY(-8px);
transition: opacity 160ms, transform 160ms, display 160ms allow-discrete;
}
#profile-menu:popover-open { opacity: 1; transform: translateY(0); }
@starting-style { #profile-menu:popover-open { opacity: 0; transform: translateY(-8px); } }
</style>- Кнопка меняет нативное состояние popover без JavaScript-обработчика.
- Меню закрывается по Escape, клику вне слоя и отдельной кнопке hide.
- Повторный запуск даёт тот же предсказуемый результат.
- Пустой ввод получает понятное сообщение вместо падения.
popovertarget задаёт управляющую кнопку, а значение auto включает взаимное закрытие и light dismiss. Найдите в примере вход, проверку и место формирования результата.

Что отличает устойчивый проект от случайного запуска. Явные границы делают ошибку локальной и понятной.
Что происходит внутри и почему это работает
Открытый popover попадает в top layer, поэтому ему не нужно соревноваться с огромными z-index внутри обычного stacking context. Браузер также создаёт неявную связь управления для доступных технологий. Логику держите отдельно от вывода: функция получает аргумент и возвращает значение, а интерфейс показывает его. Popover не всегда заменяет dialog. Если пользователь должен завершить действие до возврата к странице, нужен модальный <dialog>, а не немодальная подсказка.
| Часть | За что отвечает | Что проверить |
|---|---|---|
| Invoker | кнопка показывает, скрывает или переключает popover | атрибут указывает существующий уникальный id |
| Popover | содержит меню или подсказку в top layer | тип auto закрывается снаружи и по Escape |
| CSS | оформляет открытое состояние и начальный кадр | без анимации содержимое остаётся рабочим |
Не превращайте popover в контейнер для всего приложения. Он хорошо подходит небольшому меню, палитре действий, фильтру или подсказке. Для сложной формы решите, должна ли она быть модальной. Не удаляйте видимый focus outline и проверяйте порядок клавиатуры. Не прячьте поток в одном обработчике: сохраните вход, проверьте его, вызовите операцию и только затем обновите интерфейс.
Проверяем проект и добавляем свою функцию
Добавьте второй popover с popover="manual" для уведомления и сравните: он не закрывается от обычного light dismiss, поэтому требует явного управления. До правки запишите ожидаемое поведение одним предложением. После граничного теста повторите обычный сценарий.
- Сохраните ожидаемый результат: кнопка открывает меню, Escape и клик снаружи закрывают его, Tab проходит по ссылкам, а страница работает без отдельной библиотеки.
- Измените правило: добавьте подсказку manual и кнопку, которая закрывает её через popovertargetaction. Сначала предскажите итог.
- Передайте граничное значение и убедитесь, что приложение не падает.
- Верните корректные данные и объясните роли трёх основных частей.
- клик открывает и закрывает popover
- Escape и клик снаружи закрывают меню
- слой появляется без скачка layout
- ссылки доступны, а фокус не теряется
Нативный primitive уменьшает код только тогда, когда вы сохраняете правильную семантику меню, подсказки и диалога. Полезная правка проходит от нового ввода до видимого результата.

Четыре проверки перед следующим шагом. Каждый следующий этап начинается после наблюдаемого результата.
Что запомнить и куда двигаться дальше
Проверьте клавиатуру, масштаб 200 процентов, мобильную ширину и старый браузер. При необходимости добавьте небольшое условное улучшение, но не дублируйте нативную логику целой библиотекой. Для закрепления откройте в доступном бургер-меню, в статье про тёмную тему и в View Transitions API.
Как изучить тему в Кодике
Начните с button, nav, id и фокуса, затем изучайте top layer и дискретные переходы. Сначала восстановите главную функцию и проверьте её на трёх значениях.
| Шаг | Что разобрать | Мини-проверка |
|---|---|---|
| 1. Основа | Семантические кнопки, ссылки и фокус клавиатуры | Объясните вход и выход функции. |
| 2. Инструмент | popover, popovertarget и popovertargetaction | Повторите команду по памяти. |
| 3. Проект | Меню auto и подсказку manual | Проверьте два сценария. |
| 4. Рефакторинг | Anchor positioning и тесты доступности | Разделите ввод, логику и вывод. |
Сравните popover, dialog и обычный раскрывающийся блок, объяснив выбор для каждого сценария. Базовый синтаксис закрепите через курс HTML.
Фоновая страница остаётся доступной. Для обязательного решения используйте dialog.
Элемент выполняет не навигацию, а действие. Используйте button.
Клавиатурный пользователь теряет позицию. Оформляйте :focus-visible, но не скрывайте его.
На сенсорном экране и клавиатуре меню недоступно. Оставьте явную кнопку.
Что получится в итоге

Так выглядит законченный учебный проект: есть понятный вход, видимый результат, защита от неверных данных и место для следующего улучшения.
Что означает popover="auto"?
Такой popover поддерживает light dismiss и обычно закрывает другой auto popover при открытии.
Почему Popover API проще z-index?
Открытый элемент помещается в top layer браузера поверх обычных stacking context.
Что проверять первым, если Popover API не запускается?
Версию среды, текущую папку, команду запуска и первую строку ошибки.
Как понять, что проект Popover API работает?
Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай.
Можно ли начать с готового кода?
Да. Добейтесь результата, измените одно правило и восстановите ключевую функцию без копирования.
Выберите одно улучшение и проведите его от ввода до результата.
Если не хватает основы, перейдите курс HTML, затем восстановите ключевую функцию без подсказки.