Создание постоянных подсказок по приложению

Для ознакомительных туров требуются оверлеи, которые остаются на экране, пока пользователи взаимодействуют с выделенными функциями. В отличие от автоматических всплывающих окон, всплывающие окна, открытые вручную, не закрываются, когда пользователь нажимает в другом месте страницы. Сочетание popover="manual" с позиционированием привязки CSS позволяет создавать немодальные привязанные шаги тура.

HTML

<div id="feature-target">Highlight this feature</div>

<!-- MANDATORY: Enforce overlay dialog semantics and accessible name bindings -->
<div id="tour-step" popover="manual" role="dialog" aria-labelledby="tour-title">
  <!-- Assume an <h1> precedes this element in the full document outline -->
  <h2 id="tour-title">Step 1</h2>
  <p>Learn how to use this feature.</p>
  <button popovertarget="tour-step" popovertargetaction="hide">Got it</button>
</div>

CSS

#feature-target {
  anchor-name: --feature-target;
}

#tour-step {
  popover: manual;
  position-anchor: --feature-target;
  position-area: right center;
  inset: auto;
  margin: 1rem;
  padding: 1rem;
  border: 1px solid blue;
  border-radius: 0.5rem;
  background: aliceblue;
}

JavaScript

const tourStep = document.getElementById('tour-step');
tourStep.showPopover();
// MANDATORY: Programmatically route focus into the non-modal popover so keyboard/assistive technology users immediately perceive the new context
tourStep.querySelector('button').focus();

Руководство по реализации

  • ОБЯЗАТЕЛЬНО. Используйте popover="manual", чтобы предотвратить случайное закрытие шага тура во время взаимодействия с пользователем.
  • ОБЯЗАТЕЛЬНО. Пометьте контейнер с помощью role="dialog" и свяжите его заголовок с помощью aria-labelledby.
  • ОБЯЗАТЕЛЬНО. Сразу после открытия всплывающего окна переместите фокус внутрь него, чтобы он не остался на странице.
  • РЕКОМЕНДУЕТСЯ использовать позиционирование привязки CSS, чтобы привязать шаг тура к конкретной функции.
  • РЕКОМЕНДУЕТСЯ добавить в окно кнопку "Закрыть" или "Далее" с атрибутом popovertargetaction="hide".

Резервные стратегии

Резервные варианты и поддержка Popover в браузерах

Popover API в основном представляет собой прогрессивное улучшение, но его определяющие характеристики – продвижение верхнего слоя, легкое отклонение и вызов popovertarget – не имеют эквивалента только для CSS. Для старых браузеров нужен полифил или резервный вариант, если вы не хотите его использовать.

Полифил. Чтобы обеспечить поддержку атрибута popover в старых браузерах, условно загрузите @oddbird/popover-polyfill. ОБЯЗАТЕЛЬНО. Проверьте наличие свойства popover в HTMLElement.prototype и загрузите полифил, только если встроенная поддержка отсутствует. Не загружайте его без необходимости.

С помощью сборщика или карты импорта:

// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
  import("@oddbird/popover-polyfill");
}

Если вы не используете сборщик, импортируйте из CDN в <script type="module">:

<script type="module">
  if (!("popover" in HTMLElement.prototype)) {
    import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
  }
</script>

Ограничение, связанное со стилями. Полифил не может определить настоящий псевдокласс :popover-open, поэтому вместо него применяется класс .\:popover-open. ОБЯЗАТЕЛЬНО. Объедините эти два правила с помощью :is() или :where(), иначе браузеры, не поддерживающие :popover-open, будут игнорировать правило целиком.

[popover]:is(:popover-open, .\:popover-open) {
  display: block;
}

В качестве альтернативы для устаревшего резервного варианта без полифила используйте position: fixed и вручную рассчитайте координаты с помощью getBoundingClientRect() или используйте позиционирование по умолчанию с помощью inset: auto, если это допустимо для вашего случая.

anchor-positioning

Чтобы обеспечить поддержку браузеров без позиционирования привязки, вы можете использовать полифил или резервный вариант на чистом CSS.

Вариант 1. Резервный полифил

Полифилл @oddbird/css-anchor-positioning можно использовать для эмуляции позиционирования привязки. Неявные привязки не поддерживаются, поэтому вы ДОЛЖНЫ добавить в триггер явные названия привязок. Кроме того, полифил не поддерживает position-area во всплывающих окнах, поэтому вы ДОЛЖНЫ использовать anchor() для нужных вставок вместо position-area.

<script type="module">
  if (!CSS.supports('anchor-name: --foo')) {
    await import("https://unpkg.com/@oddbird/css-anchor-positioning");
  }
</script>
#tour-step {
  /* If using the anchor positioning polyfill with a popover, DO use `anchor()` functions instead of `position-area`. */
  left: anchor(right);
  top: anchor(top);
}
Вариант 2. Резервный код CSS без полифила

Если вы не хотите использовать полифил, то можете закрепить подсказку внизу области просмотра с помощью @supports not.

@supports not (anchor-name: --foo) {
  #tour-step {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    margin: 0;
    border-radius: 0;
  }
}