Webパーツ辞典

ポップオーバーPopover

押した要素のそばに、小さな窓を重ねて出す部品。背後の操作は止めない点がモーダルと違う。

表示例

コンパクト表示

画像を隠す

別名・英語表記

  • ポップアップ
  • 吹き出しパネル
  • ポップ
  • 小窓
  • ふきだしパネル
  • Popover

実装例

<div class="x-popover">
  <button class="x-popover__b" type="button" aria-expanded="true" aria-controls="x-popover-p">
    表示の設定
  </button>
  <!-- 見本なので開いた状態で流れの中に置いている。実際は中身に popover 属性、ボタンに popovertarget="x-popover-p" を付けて開閉し、
       aria-expanded は false から始めて toggle イベントで書き換える(hidden 属性では閉じない) -->
  <div class="x-popover__p" id="x-popover-p">
    <p class="x-popover__i">コンパクト表示</p>
    <p class="x-popover__i">画像を隠す</p>
  </div>
</div>

AIへの指示文

「ポップオーバー(Popover)」を実装してください。

## これは何か
押した要素のそばに、小さな窓を重ねて出す部品。背後の操作は止めない点がモーダルと違う。

## 使いどころ
- 補足の説明や、短い設定をその場で出したいとき
- 一覧の行ごとに、詳細をちらっと見せたいとき

## 実装の要件
- button[type=button][popovertarget="id"][aria-expanded][aria-controls="id"] + div[popover][id] の構成にする
- Esc や外側を押したときに閉じる動きと、Esc で閉じたときにフォーカスを開く前の要素(キーボードで開いたならそのボタン)へ戻す動きはブラウザが持つので、JavaScript で書き足さない(Chrome・Edge は 114 から、Safari は 17 から、Firefox は 125 から。iOS の Safari が外側のタップで閉じるのは 18.3 から)
- 位置は CSS アンカー配置で決める。popovertarget で結んだボタンが暗黙のアンカーになるので、中身に position-area: block-end span-inline-end; を付け、ボタンの下に左端をそろえて出す(Chrome・Edge は 133 から、Safari は 26 から、Firefox は 147 から)
- 画面の端でのはみ出しは、中身に position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline; を付けて回す。下端では上へ、右端ではボタンの右端にそろえて左へ、右下の角では左上へ回る
- 中身の margin: 6px 0 0; inset: auto; width: max-content; と position-area・position-try-fallbacks は、見本の margin-top も含めて @supports (position-area: block-end) の中だけに書く
- これらを @supports の外に書くと、未対応の版(Safari 18 以前・Firefox 146 以前)で画面の端に張りつく
- width: max-content を外さない。既定の width: fit-content のままだと、右端では左へ回らずに残りの幅まで細く縮む
- position-area に対応しないブラウザ向けに、@supports not (position-area: block-end) の中で中身に margin: auto; を書き、画面の中央に出す(popover の既定の margin: auto に頼ると、margin を 0 にするリセット CSS に消されて画面の端に張りつく)
- 中身を詰め込むとモーダルにすべきだった、という形になる。3〜4項目までに留める
- 画面の端で見切れやすい。下や右に収まらないときは上や左へ反転させる(反転はアンカー配置の position-try-fallbacks でブラウザに任せる)
- ホバーだけで開くとタッチ端末で開けない。クリックでも開くようにする

## アクセシビリティの要件
- 開くボタンに aria-expanded を付け、aria-controls で中身を指す
- aria-expanded は中身の toggle イベントの newState(open / closed)に合わせて true / false に書き換え、外側クリックや Esc で閉じたときも古い値を残さない
- Esc で閉じたとき、フォーカスが開く前の要素(キーボードで開いたならそのボタン)へ戻る。ブラウザが持つ動きなので、閉じたときに JavaScript でボタンへ focus() しない(外側を押して閉じたときにフォーカスを奪う)
- 外側を押したときも閉じる。popover 属性なら、この動きと重ね順をブラウザが持つ

## 参考にする実装
この形を出発点にして、プロジェクトの命名規則・色・余白に合わせて調整してください。

```html
<div class="x-popover">
  <button class="x-popover__b" type="button" aria-expanded="true" aria-controls="x-popover-p">
    表示の設定
  </button>
  <!-- 見本なので開いた状態で流れの中に置いている。実際は中身に popover 属性、ボタンに popovertarget="x-popover-p" を付けて開閉し、
       aria-expanded は false から始めて toggle イベントで書き換える(hidden 属性では閉じない) -->
  <div class="x-popover__p" id="x-popover-p">
    <p class="x-popover__i">コンパクト表示</p>
    <p class="x-popover__i">画像を隠す</p>
  </div>
</div>
```

```css
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-popover,
.x-popover *:not([class*="fa-"]),
.x-popover *:not([class*="fa-"])::before,
.x-popover *:not([class*="fa-"])::after {
  box-sizing: border-box;
  /* 貼った先の既定の書体に引きずられないようにする。書体が変わると
     文字の幅と高さが変わり、枠のサイズまでずれる */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}

.x-popover {
  position: relative;
  width: 170px;
}
.x-popover__b {
  width: 100%;
  min-height: 36px;
  border: 1px solid #cfd4dc;
  border-radius: 8px;
  background: #fff;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.x-popover__p {
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid #e3e6ea;
  border-radius: 8px;
  background: #fff;
}
.x-popover__i {
  margin: 0;
  padding: 4px 0;
  font-size: 11.5px;
}
```

## 出力の約束
- HTML と CSS を分けて出す。JavaScript が要るときは素の JavaScript で書き、UIフレームワークは使わない。
- 参考実装がアイコンに Font Awesome のクラスを使っている場合は、プロジェクトで使っているアイコンかインライン SVG に置き換えてよい。
- 上のアクセシビリティ要件を満たす。満たせない箇所があるときは、理由を添えて先に知らせる。
- 色・角丸・余白は既存のデザイントークンがあればそれを使う。無ければ CSS 変数として切り出す。

使いどころ

  • 補足の説明や、短い設定をその場で出したいとき
  • 一覧の行ごとに、詳細をちらっと見せたいとき

注意点

  • 中身を詰め込むとモーダルにすべきだった、という形になる。3〜4項目までに留める
  • 画面の端で見切れやすい。下や右に収まらないときは上や左へ反転させる(反転はアンカー配置の position-try-fallbacks でブラウザに任せる)
  • ホバーだけで開くとタッチ端末で開けない。クリックでも開くようにする

アクセシビリティの要点

  • 開くボタンに aria-expanded を付け、aria-controls で中身を指す
  • aria-expanded は中身の toggle イベントの newState(open / closed)に合わせて true / false に書き換え、外側クリックや Esc で閉じたときも古い値を残さない
  • Esc で閉じたとき、フォーカスが開く前の要素(キーボードで開いたならそのボタン)へ戻る。ブラウザが持つ動きなので、閉じたときに JavaScript でボタンへ focus() しない(外側を押して閉じたときにフォーカスを奪う)
  • 外側を押したときも閉じる。popover 属性なら、この動きと重ね順をブラウザが持つ

見分け方

関連するパーツ