Popover – это нечто среднее между классической подсказкой (tooltip) и модальным окном (popup). В отличие от всплывающих подсказок, которые появляются при наведении и содержат минимальную информацию, popover активируется по клику на кнопку и, как правило, содержит набор действий или элементов управления.
Типичный пример использования – меню действий у карточки товара или статьи: «Подписаться», «Поделиться», «Пожаловаться», «Добавить в избранное». Такое меню нужно для каждого элемента на странице, но дублировать его разметку в каждой карточке – не лучшая практика. Здесь на помощь приходит современный нативный API – popover.
Кроме того, такое нативное решение имеет следующие плюсы:
- Top Layer: Он помещается в специальный слой верхнего уровня браузера, а значит, больше не нужно сражаться с
z-index: 999999и проблемамиoverflow: hiddenу родительских контейнеров. - A11y (Доступность): Нативный поповер автоматически связывает фокус, обрабатывает
Escи делает UI доступным для клавиатуры и скринридеров из коробки без написания WAI-ARIA атрибутов вручную.
Реализация
Сам механизм предельно прост и не требует написания JavaScript-обработчиков.
Кнопка-триггер popover.
<button type="button" popovertarget="reaction-popover">Выбрать реакцию</button>
Достаточно атрибута popovertarget, значение которого должно совпадать с id целевого поповера. Для более гибкого управления можно использовать атрибут popovertargetaction, который может принимать значения show, hide или toggle (по умолчанию).
Размещается в конце документа, например, после <footer>. Стилизован с использованием плавного появления, а позиционирование реализовано через современное CSS-свойство position-area.
Показать HTML код
<div id="reaction-popover" class="reaction-popover" popover>
<button type="button" aria-label="Оставить реакцию: сердце">❤️</button>
<button type="button" aria-label="Оставить реакцию: лайк">👍</button>
<button type="button" aria-label="Оставить реакцию: дизлайк">👎</button>
<button type="button" aria-label="Оставить реакцию: в шоке">😲</button>
<svg class="reaction-popover-corner" viewBox="0 0 16 8" aria-hidden="true">
<path d="M0 0 L6.2 6.2 C7.2 7.2 8.8 7.2 9.8 6.2 L16 0 H0 Z" />
</svg>
</div>Показать CSS код
#reaction-popover {
opacity: 0;
translate: 0 -2rem;
transition-property: display, overlay, opacity, translate;
background: black;
width: fit-content;
gap: 0.5rem;
overflow: visible;
border-radius: calc(infinity * 1px);
padding: 0.5rem;
font-size: 1.25rem;
transition-behavior: allow-discrete;
transition-duration: 0.5s;
&:popover-open {
display: flex;
opacity: 100%;
translate: 0 -0.5rem;
@starting-style {
opacity: 0%;
translate: 0 -2rem;
}
}
& button {
transition-duration: 0.3s;
&:hover {
@media (hover: hover) {
opacity: 80%;
}
}
}
& .reaction-popover-corner {
fill: black;
position: absolute;
inset-inline: 0;
top: 100%;
margin-inline: auto;
height: 0.5rem;
width: 1rem;
}
@supports (anchor-name: --anchor) {
/* Отступы по бокам экрана, чтобы не приклеивался */
margin-inline: 1rem;
inset: auto;
position-area: top;
}
@supports not (anchor-name: --anchor) {
position: fixed;
inset: 1rem;
margin: auto;
}
}С таким подходом мы не дублируем это меню в каждой карточке. Но если браузер не поддерживает
position-area, то придётся позиционировать его по центру экрана, а не относительно кнопки. Или
писать отдельный скрипт. На июль 2026 поддержка браузерами составляет 81%.
А сам popover имеет поддержку 89% (Baseline 2025).