Dialog と Popover #10
Intro
ここまで解説した仕様を踏まえ、いくつかの代表的なユースケースの実装について考えていく。
あくまで仕様の組み合わせ方についての解説であり、実装そのものの推奨ではない。
また、ここで紹介する仕様はまだ変更の可能性があり、かつ実装も揃っていないものがある点に注意
Tooltip
今回は、 Menu の実装を考えてみる。 GitHub でいうとこの部分だ。
元となるボタンによって表示され、このボタンからの相対位置で調整されるため Anchor Positioning を活用することになる。非常に良くある実装パターンだ。
HTML の仕様にも、類似の実装が Example として掲載されている。
- 6.12 The popover attribute
APG としては、 Menu Button パターンにあたるだろう。
- Menu Button Pattern | APG | WAI | W3C
GitHub のこの実装はまだ Popover ではないため、現状を参考にどのように Popover で実装できるかを考えてみる。
よくあるメニューとして、以下のような HTML をベースに考える。
開くためのボタンが Invoker となり、 Popover としてメニューのアイテムが開く実装が考えられるだろう。
ここでも Popover はセマンティクスに影響を与えないため、単に 最初のコントローラには明示的に APG などにも書かれているように、従来このような実装を行う際は、 しかし、 Popover が Invoker Relationship を持っている場合、 これが基本の構造となる。
今回はとりあえずパッと表示されて、終わったら消えればよいということで、アニメーションは割愛する。
問題は表示位置だ。
基本的には、開く側のボタンに対して相対的に表示するため、ボタンをアンカーとして指定する。
あとは、 あとは、通常通り必要なスタイルを当ててやれば良い。
Popover の開閉という点に関しては、特に JS 無しに挙動が実現できているため、特に必要は無い。
あとは、普通にメニューの機能そのものを実装すれば良いだろう。
HTML
<button popovertarget=menu>Actions</button>
<ul id=menu popover>
<li><button>Edit</button></li>
<li><button>Hide</button></li>
<li><button>Delete</button></li>
</ul>
<ul>
が開いただけになる。この場合、外側は role=menu
とし、各アクションが role=menuitem
とすることで、開いているものがメニューであると言うことを宣言できるだろう。
<button popovertarget=menu>Actions</button>
<ul id=menu role=menu popover>
<li role=menuitem><button>Edit</button></li>
<li role=menuitem><button>Hide</button></li>
<li role=menuitem><button>Delete</button></li>
</ul>
autofocus
を付与し、各操作実行後には Popover を閉じるために popovertargetaction=close
も担わせることができる。
<button popovertarget=menu>Actions</button>
<ul id=menu role=menu popover>
<li><button role=menuitempopovertarget=menu popovertargetaction=close autofocus>Edit</button></li>
<li><button role=menuitempopovertarget=menu popovertargetaction=close>Hide</button></li>
<li><button role=menuitempopovertarget=menu popovertargetaction=close>Delete</button></li>
</ul>
<button popovertarget>
をクリックしたことで <ul role=menu>
が開いたと言う事実を UA に伝えるために、 aria-haspopup=menu
を付与し、メニューが開いている間は aria-expanded=true
にするといった実装が行われていた。
<button popovertarget>
が <ul role=menu>
を開いたことを UA は認識しているため、このような実装は Popover API を用いる限りは不要となる。これも Popover がネイティブの API になったことのメリットの 1 つだ。
aria-haspopup
· Issue #9153 · whatwg/html
CSS
button[popovertarget] {
anchor-name: --menu;
}
ul[popover] {
position-anchor: --menu;
}
[popovertarget]
に合わせて位置を指定し、必要に応じて translate
で調整することで実装ができるだろう。
[popover] {
top: anchor(end);
left: anchor(center);
translate: 2% 4%;
}
position-area
を用いて指定する場合は、以下のようにも指定可能だ。
[popover] {
position-area: bottom span-right;
}
JS
DEMO
動作するデモを以下に用意した。
- Menu Popover DEMO