表示例
コンパクト表示
画像を隠す
別名・英語表記
- ポップアップ
- 吹き出しパネル
- ポップ
- 小窓
- ふきだしパネル
- 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>
/* 貼った先のリセットに頼らないよう、この部品の中だけ 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;
}
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 属性なら、この動きと重ね順をブラウザが持つ