Popover(クリックで開く小窓)
Popover は、ボタンを押すとそのすぐそばに小さな窓を開く UI コンポーネントです。popover 属性での作り方と、出る向き・そろえ方の指定をまとめます。
Popover は、ボタンを押すと、そのボタンのすぐそばに小さな窓(ポップオーバー)を開くコンポーネントです。ブラウザにもともとある Popover API(popover 属性と popovertarget 属性で、窓を開け閉めするしくみ)だけで動くので、JavaScript は要りません。
どんなときに使う?#
- 言葉の補足や、ちょっとした説明を、押したときだけ見せたいとき
- 小さなメニューや、お知らせを出したいとき
画面全体をおおって見せたいときは Modal(モーダル)、マウスを乗せたときに短い説明を出したいときは Tooltip(ツールチップ) が向いています。
使い方#
b--popover の箱の中に、開くボタン(b--popover_trigger)と窓(b--popover_popup)を入れます。ボタンの popovertarget と、窓の id に同じ名前を書きます。窓には popover="auto" を付けます。
表示例
窓の中身です。外を押すか Esc キーで閉じます。
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-1">開く</button>
<div class="b--popover_popup -max-w" id="demo-pop-1" popover="auto" data-side="bottom" data-align="center" style="--max-w:16rem">
<p>窓の中身です。外を押すか Esc キーで閉じます。</p>
</div>
</div>
| クラス | 付ける場所 |
|---|---|
b--popover |
全体を包む箱 |
b--popover_trigger |
開くボタン(button 要素) |
b--popover_popup |
開く窓 |
b--popover_close |
窓の中に置く、閉じるボタン(button 要素) |
popover="auto" にしておけば、開け閉めの細かい動きは自分で作らなくてかまいません。ブラウザが受け持つのは次の4つです。
- 開け閉め:ボタンを1回押すと開き、もう1回で閉じます
- かんたんに閉じる:窓の外をクリックしても、Esc キーでも閉じます。この動きを light dismiss といいます
- 選択の戻し先:閉じると、キーボードの選択(フォーカス)がボタンへ戻ります
- 読み上げ用の印:開いているかどうかを表す
aria-expanded(読み上げソフト向けの属性)が、ボタンの上で自動で変わります
窓の中で Tab キーを押して、選択が外へ出ても、窓は開いたままです(Popover API がそう決めています)。外へ出たら閉じたいなら、focusout イベントのときに hidePopover() を呼ぶ処理を、自分で用意します。
- ボタンは
button要素で作ります。popovertarget属性が働くのはbuttonやinput type="button"などだけです。閉じるボタンも同じです - 窓が閉じているとき、中身は読み上げソフトからも見えなくなります。だから、なくてはならない情報やボタンは、窓の外にも置きます
- 窓に
roleは付けていません。中にフォームなどの操作をまとめて入れるなら、自分でrole="dialog"とaria-labelを足します
出る向きとそろえ方#
窓の data-side で出る向きを、data-align でそろえる位置を決めます。
| 属性 | 値 | 初期値 |
|---|---|---|
data-side |
top(上)・bottom(下)・start(左)・end(右) |
bottom |
data-align |
start・center・end |
center |
data-side が top・bottom のときは data-align が横のそろえ方に、start・end のときは縦のそろえ方になります。
表示例
bottom / start
bottom / end
top / center
<div class="l--cluster -g:10">
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-2">下・左寄せ</button>
<div class="b--popover_popup -max-w" id="demo-pop-2" popover="auto" data-side="bottom" data-align="start" style="--max-w:12rem">
<p>bottom / start</p>
</div>
</div>
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-3">下・右寄せ</button>
<div class="b--popover_popup -max-w" id="demo-pop-3" popover="auto" data-side="bottom" data-align="end" style="--max-w:12rem">
<p>bottom / end</p>
</div>
</div>
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-4">上</button>
<div class="b--popover_popup -max-w" id="demo-pop-4" popover="auto" data-side="top" data-align="center" style="--max-w:12rem">
<p>top / center</p>
</div>
</div>
</div>
start・endは、文字を書く向き(書字方向)に合わせて決まります。左から右へ書くページ(dir="ltr")ではstartが左、endが右です。右から左へ書くページ(dir="rtl")では逆になります- 窓が画面のはしに入りきらないときは、自動で反対側に出ます
専用の変数#
どれも b--popover(またはその外側の要素)に書きます。窓(b--popover_popup)に書いても効きません。
| 変数 | 決めること | 初期値 |
|---|---|---|
--popover-offset |
ボタンと窓のあいだのすきま | var(--s5) |
--popover-duration |
開け閉めでふわっと変わる時間 | 0.15s |
--popover-arrow |
吹き出しの矢印の高さ(0 で矢印なし) |
6px |
動きを減らす設定(prefers-reduced-motion: reduce)の画面では、開け閉めの時間は 0s になります。
見た目を変える#
窓は、はじめは背景が var(--base)、余白が 0.75em 1em、影の付いたカードの形です。角は丸くありません。色・余白・角丸・影は、-bgc・-c・-p・-bdrs・-bxsh などのクラスで変えます。矢印は窓の背景の色に合わせて変わり、-bd で枠線を付けると、矢印にも同じ色と太さの縁が付きます。
表示例
背景と文字の色を入れかえました。
矢印にも縁が付きます。
<div class="l--cluster -g:10">
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-5">色を変える</button>
<div class="b--popover_popup -bgc:text -c:base -max-w" id="demo-pop-5" popover="auto" data-side="bottom" data-align="center" style="--max-w:12rem">
<p>背景と文字の色を入れかえました。</p>
</div>
</div>
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-6">枠線を付ける</button>
<div class="b--popover_popup -bd -bdc:current -max-w" id="demo-pop-6" popover="auto" data-side="bottom" data-align="center" style="--bdw:2px;--max-w:12rem">
<p>矢印にも縁が付きます。</p>
</div>
</div>
</div>
閉じるボタンで閉じる(manual)#
窓を popover="manual" にすると、外を押しても Esc キーでも閉じなくなります。そのため、閉じるボタンを必ず置きます。閉じるボタンには popovertarget と popovertargetaction="hide" を付けます。
表示例
閉じるボタンを押すまで開いたままです。
<div class="b--popover">
<button class="b--popover_trigger set--plain -bd -px:15 -py:5 -bdrs:10 -hov:-bgc" type="button" popovertarget="demo-pop-7">お知らせを見る</button>
<div class="b--popover_popup -max-w -bd" id="demo-pop-7" popover="manual" data-side="bottom" data-align="center" style="--max-w:16rem">
<div class="l--stack -g:5">
<div class="l--flex -ai:center -jc:between -g:15">
<span class="-fw:bold">お知らせ</span>
<button class="b--popover_close set--plain -fz:l -hov:-c" type="button" popovertarget="demo-pop-7" popovertargetaction="hide">×<span class="u--srOnly">閉じる</span></button>
</div>
<p>閉じるボタンを押すまで開いたままです。</p>
</div>
</div>
</div>
ブラウザによる違い#
窓をボタンのそばに置くのには、CSS Anchor Positioning(ある要素を目じるしにして、別の要素の位置を決める CSS のしくみ)を使っています。Firefox ESR 140 のように、このしくみを使えないブラウザでは、窓は画面の真ん中に出ます。そのときは、向き・そろえ方・すきまの指定は効きません。開け閉め・外を押して閉じる・選択を戻す動きは Popover API の働きなので、そのまま使えます。
しくみ#
おもな CSS は次のとおりです(位置を決める部分は長いので省いています)。
.b--popover {
--duration: var(--popover-duration, 0.15s);
--offset: var(--popover-offset, var(--s5));
--arrow-sz: var(--popover-arrow, 6px);
display: inline-block;
}
.b--popover_popup {
border: none;
font-size: var(--fz--s);
color: var(--text);
background-color: var(--base);
box-shadow: var(--bxsh--30);
overflow: auto;
padding: 0.75em 1em;
opacity: 0;
}
.b--popover_popup:popover-open {
opacity: 1;
}
React・Astro で書く場合#
@lism-css/ui/react/Popover(Astro は @lism-css/ui/astro/Popover)から Popover を読み込みます。部品は <Popover.Root>・<Popover.Trigger>・<Popover.Popup>・<Popover.Close> です。<Popover.Root> の中に置くと、popovertarget と id が自動でつながります。
import { Popover } from '@lism-css/ui/react/Popover';
<Popover.Root popoverId="pop-01">
<Popover.Trigger bd px="15" py="5" bdrs="10" hov="-bgc">開く</Popover.Trigger>
<Popover.Popup side="top" align="start" max-w="20rem">
<p>中身</p>
</Popover.Popup>
</Popover.Root>
| Props | 決めること |
|---|---|
popoverId |
<Popover.Root> 用。ボタンと窓をつなぐ名前。書かなければ自動で作られる |
offset |
<Popover.Root> 用。ボタンと窓のすきま(--popover-offset になる) |
side |
<Popover.Popup> 用。出る向き(data-side になる。初期値 bottom) |
align |
<Popover.Popup> 用。そろえ方(data-align になる。初期値 center) |
type |
<Popover.Popup> 用。auto か manual(popover 属性になる。初期値 auto) |
icon |
<Popover.Close> 用。中身を渡さないときのアイコン(初期値 x) |
srText |
<Popover.Close> 用。読み上げ用の文字(初期値 Close) |
popoverId・id |
<Popover.Trigger>・<Popover.Close> の popoverId と <Popover.Popup> の id。<Popover.Root> を使わず、部品を離して置くときだけ書く |
<Popover.Root> の中では、部品それぞれに popoverId や id を書かないでください。一部だけに書くと、つながりが切れます。名前を決めたいときは <Popover.Root> の popoverId だけを使います。
srText の初期値は英語の Close です。日本語のサイトでは srText="閉じる" と書くのがおすすめです。
関連するページ#
- Tooltip(ツールチップ):マウスを乗せたときの短い説明
- Modal(モーダル):画面全体をおおう窓
- UI コンポーネントの使い方:読み込み方
公式ドキュメント
2026年10月5日時点の内容(lism-css 1.0.1・@lism-css/ui 0.40.1)をもとに、やさしい日本語でまとめています。