概要
普段使ってるGitHubのUIパーツの実装を見てみたら真似したいエッセンスがあったので紹介します。
GitHub上でちょいちょい使われてるポップアップメニュー
なにが優れてる?
- Javascript使ってない
- メニュー外をクリックしたらメニューが閉じる
サンプルコード
<div class="wrap">
<details>
<summary>button</summary>
<div>menu</div>
</details>
</div>
*,
*:before,
*:after {
box-sizing: border-box;
}
.wrap {
width: 500px;
height: 500px;
margin: 0 auto;
padding: 50px 50px;
}
details > div {
position: absolute;
display: block;
width: 200px;
height: 200px;
border: 1px solid rgba(27, 31, 35, 0.15);
border-radius: 3px;
box-shadow: 0 3px 12px rgba(27, 31, 35, 0.15);
z-index: 100;
}
details[open] > summary:before {
content: " ";
display: block;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 50;
background: transparent;
}
Javascript使ってない
GitHubで使われてるHTMLタグをみてみましょう
<details>
<summary>
メニュー開くボタン
</summary>
<details-menu>
コンテンツ内容
</details-menu>
</details>
ポップアップメニューは、details
とsummary
というタグで構成されています。
(details-menu
はカスタムエレメントです。今回は割愛してdivとして扱います。)
details
とsummary
は,HTML5.1にて追加されたHTMLタグです。
Detailsタグとは
HTML の詳細折りたたみ要素 (
<details>
) は、ウィジェットが open 状態になった時のみ情報が表示される折りたたみウィジェットを作成します。概要やラベルは<summary>
要素を使用して提供することができます。
このタグを装飾することでメニューの開閉をJavascriptなしで実現することが出来ます。
今回の例ではdetails > div
をposition: absolute
として、box-shadow
で影を落とすことで、浮き出たメニューを表現しています。
detailsタグを使う以外にもJavascriptなしでこのような開閉メニューを作る方法あります。
見えないcheckboxを作って、checked属性の有無でスタイルを変更するというテクニックです。
しかし、checkboxはそう行った目的のタグではないため、メニューの開閉に使うというのは直感的ではありません。
details、summaryの方が表示の開閉をイメージしやすく直感的なためこちらの方が目的にあったタグだと考えます。
(対応ブラウザの話はさておいて)
メニュー外をクリックした時にメニューが閉じる
detailsタグをそのまま使っただけでは、summary部分をクリックしない限り閉じてくれません。
GitHubでは、:beforeを使ったテクニックを使っていました。
わかりやすくするために:beforeの要素を赤い半透明にしてみました。
メニュー外に透明な当たり判定用のパネルを広げているんですね。
:beforeを使わない場合は、Javascriptで処理を書かなければいけないと思いますが、
このやり方だとJavascriptなしでスッキリかけますね。
デメリット
- detailsタグは、IE、EDGEで使えない
- Polyfillがあるのでそれで対応したい
- 開閉のアニメーションが出来ない
- Mozilla情報だと出来ないらしい(出来そうな気もする、未検証)
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/details
まとめ
- GitHubのポップアップメニューはJavascriptなしで動いてすごい
- detailsタグ
- HTML5.1で追加になった
- 詳細折りたたみ要素
- めっちゃいいけどIEとEDGE未対応
- 透明な:beforeをヒットボックスにするアイデアいいね