永続的なアプリツアーの作成

オンボーディング ツアーでは、ユーザーがハイライト表示された機能を操作している間、オーバーレイを維持する必要があります。自動ポップオーバーとは異なり、手動ポップオーバーは、ユーザーがページ上の別の場所をクリックしても閉じません。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 を読み込みます。必須: HTMLElement.prototype の popover プロパティをチェックして機能を検出し、ネイティブ サポートがない場合にのみポリフィルを読み込みます。無条件に読み込まないでください。

バンドラまたはインポート マップを使用する場合:

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

バンドラを使用しない場合は、<script type="module"> 内の CDN からインポートします。

<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() を使用して 2 つを結合します。そうしないと、: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 はポリフィルによるポップオーバーではサポートされていないため、position-area ではなく、目的のインセットで anchor() を使用する必要があります。

<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;
  }
}