[Перевод] Popover = hint
Эта статья — перевод оригинальной статьи «Popover = hint»
Также я веду телеграм канал «Frontend по‑флотски», где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Chrome 133 развивает существующую функцию всплывающих подсказок, представляя новый режим: popover="hint"
. Этот режим, управляемый браузером, позволяет использовать новый контекст наложения, упрощающий создание всплывающих подсказок и подобных эфемерных плавающих элементов. Он снижает трудозатраты разработчиков, сохраняя гибкость дизайна.
Введение и история
API Popover, представленный в Chrome 114, позволяет создавать доступные плавающие пользовательские интерфейсы, такие как меню и всплывающие подсказки. По умолчанию popover="auto"
управляет функциями отключения света и управления фокусом, не требуя дополнительных сценариев, как описано в разделе Знакомство с API Popover. При открытии поповера с popover="auto"
все остальные безпредковые поповеры с popover="auto"
будут закрыты, что обеспечивает эргономичность API, который делает наиболее разумные вещи.
Поповеры, закрывающие другие поповеры
First Popover
Second Popover
В этом примере открытие popover 2 приведет к закрытию popover 1, поскольку popover="auto"
позволяет одновременно открывать только один такой popover.
Хотя такое поведение хорошо работает для меню и диалогов, оно может создавать проблемы, когда необходимо сосуществование нескольких типов плавающего пользовательского интерфейса. Например, меню и всплывающая подсказка, использующие popover="auto"
, могут конфликтовать, когда открытие всплывающей подсказки приводит к закрытию меню. Такая ситуация может показаться необычной, но она часто встречается в современных пользовательских интерфейсах в стиле приложений. Например, меню в шапке github.com используют всплывающие окна и для меню, и для всплывающих подсказок, позволяя при определенных условиях видеть их одновременно:

Одним из способов решения этой проблемы является использование popover="manual"
для элементов всплывающих подсказок, что позволяет полностью контролировать всплывающие подсказки с помощью скриптов. Однако для этого необходимо переделать поведение стека, рассеивание света и управление фокусом — именно те задачи, для решения которых был создан Popover API. Это подтолкнуло нас к поиску путей расширения API для обеспечения недостающей функциональности.
В ходе исследований, проведенных разработчиками, мы выявили два распространенных контекста наложения:
Постоянный пользовательский интерфейс: Например, меню и диалоговые окна.
Эфемерный пользовательский интерфейс: Например, наведенные карточки и всплывающие подсказки.
Чтобы учесть оба варианта, popover="hint"
вводит второй стек, отличный от popover="auto"
, гарантируя, что меню останется открытым даже при появлении всплывающих подсказок. Вместо того чтобы вводить несколько контекстов наложения для разных типов пользовательского интерфейса, что, по сути, означало бы повторное изобретение z-index
, этот подход упрощает ситуацию, определяя всего две широкие категории: постоянный пользовательский интерфейс (auto) и эфемерный пользовательский интерфейс (hint). Это позволяет найти баланс между гибкостью и предотвращением повторного возникновения тех же проблем, с которыми вы сталкивались до использования popover.
Поведение нового значения
И popover="auto"
, и popover="hint"
поддерживают легкое закрытие, то есть они автоматически закрываются, когда пользователь щелкает за их пределами или нажимает Esc на клавиатуре. В этом отношении оба стиля идентичны.
Когда речь идет о принудительном скрытии других всплывающих окон, popover="auto"
закрывает все другие всплывающие окна авто и подсказки при открытии, гарантируя, что только одно такое окно будет активно одновременно (единственным исключением здесь являются вложенные всплывающие окна, о которых речь пойдет ниже). popover="hint"
, с другой стороны, принудительно скрывает только другие всплывающие окна подсказки, позволяя меню и всплывающим окнам оставаться открытыми и сосуществовать.
Больше всего они различаются по вложенности. popover="auto"
поддерживает вложенность, позволяя дочернему поповеру оставаться открытым внутри другого родительского поповера. popover="hint"
имеет особое поведение по вложенности, в котором участвуют отдельные «стопки». Когда поповер с подсказкой находится внутри автопоповера, он присоединяется к автостеку, чтобы сохранить контекстную группировку, то есть он будет оставаться открытым до тех пор, пока другие автоповеры или поповеры с подсказкой не заставят его принудительно скрыться. Это обеспечивает интуитивное поведение, при котором всплывающие подсказки не мешают другим меню или всплывающим окнам.
Наконец, для самых разных случаев использования всегда есть popover="manual"
, который не содержит ни одного из этих поведений, позволяя вам определить точную функциональность и поведение, которые вам нужны.
popover=«auto» | popover=«hint» | popover=«manual» | |
Лёгкое закрытие | Да | Да | Нет |
Принудительно скрывает | Несвязанные auto и hint | Несвязанные hint | Ничего |
Вложенность | Да | Особая (описано ранее) | N/A — нет лёгкого закрытия |
Триггер наведения
Распространенным UX-шаблоном являются всплывающие подсказки и ховеркарты, которые срабатывают при наведении курсора. Наведение курсора мыши на интересующий элемент в течение определенного времени приводит к показу наведенной карточки. В настоящее время такое поведение необходимо реализовать с помощью JavaScript, например, добавив слушателей для событий mouseenter
и mouseleave
. Однако в разработке находится еще один API, который должен сделать триггер ховера декларативным: API Interest Invokers.
Работа над этим API еще не завершена, но общая идея состоит в том, чтобы добавить атрибут interesttarget
ко многим типам элементов, который наделяет их поведением, вызывающим наведение курсора:
Hover to show the hovercard
This is the hovercard
При использовании предыдущего HTML наведение курсора на ссылку автоматически покажет всплывающее окно my-hovercard. Если переместить указатель на этот элемент, всплывающее окно будет скрыто. И все это без JavaScript!
Примеры
More info about the button
[popover] {
margin: 0;
inset: auto;
position-area: bottom right;
}
const button = document.querySelector('button');
const popover = document.querySelector('[popover]');
button.onmouseenter = () => {
setTimeout(() => {
popover.showPopover({source: button});
}, 500);
}
button.onmouseleave = () => {
setTimeout(() => {
popover.hidePopover();
}, 500);
}

В этом примере используется popover="hint"
для создания базовой всплывающей подсказки, которая предоставляет дополнительную информацию о кнопке при наведении на нее мыши. Активация наведения обеспечивается обработчиками событий mouseenter
и mouseleave
с простыми задержками в 0,5 секунды. Обратите внимание, что есть несколько деталей, которые не обрабатываются в этом примере:
Наведение на сам всплывающий элемент не предотвращает закрытие всплывающего элемента при наведении на него. Поэтому, например, невозможно скопировать или вставить текст из всплывающего окна.
Никакого «debouncing» нет: достаточно навестись на кнопку на небольшую долю секунды, чтобы сработало всплывающее окно, даже если кнопка будет быстро отведена до истечения времени задержки. В этом случае всплывающая подсказка «мерцает», быстро открываясь и закрываясь.
Пример вообще недоступен: любой пользователь, не использующий мышь, не может получить доступ к содержимому всплывающей подсказки.
Эти недостатки можно исправить с помощью дополнительного JavaScript. Например, необходимо добавить обработчики событий focus (или, возможно, keydown и keyup) для поддержки активации всплывающей подсказки с помощью клавиатуры. Объяснение того, что нужно правильно обработать, чтобы всплывающая подсказка была доступной, можно найти в этой замечательной записи в блоге Сары Хигли. Все эти вопросы (и многие другие) будут автоматически решаться декларативно с помощью API Interest Invokers.