GitHubのポップアップメニューはdetailsタグと:beforeが使われててクレバーだった

## 概要
普段使ってるGitHubのUIパーツの実装を見てみたら真似したいエッセンスがあったので紹介します。

## GitHub上でちょいちょい使われてるポップアップメニュー

![Nov-29-2019 22-44-08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/d2801650-a5c5-b492-6da5-895d4ede5497.gif)
図 マイページのコンテキスト切り替えメニュー


![Nov-29-2019 22-27-24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/b610a0f6-637f-fa65-215e-5b1d02e1a933.gif)
図 プルリクエストページのプロジェクト選択メニュー

## なにが優れてる？

- Javascript使ってない
- メニュー外をクリックしたらメニューが閉じる

## サンプルコード
https://codepen.io/y-tsuzaki/pen/abzoOgL

![Nov-29-2019 23-05-14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/5e527909-0789-1b97-99a9-5cbac6347596.gif)

```html
<div class="wrap">
  <details>
    <summary>button</summary>
    <div>menu</div>
  </details>
</div>
```

```css
*,
*: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タグをみてみましょう

```html:HTML抜粋したコード
<details>
  <summary>
    メニュー開くボタン
  </summary>
  <details-menu>
　　コンテンツ内容
  </details-menu>
</details>
```

ポップアップメニューは、`details`と`summary`というタグで構成されています。
(`details-menu`はカスタムエレメントです。今回は割愛してdivとして扱います。)

`details`と`summary`は,HTML5.1にて追加されたHTMLタグです。

#### Detailsタグとは
> HTML の詳細折りたたみ要素 (`<details>`) は、ウィジェットが open 状態になった時のみ情報が表示される折りたたみウィジェットを作成します。概要やラベルは` <summary> `要素を使用して提供することができます。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/details

![Nov-29-2019 23-23-40.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/26de8ebe-1f2e-c614-fcf8-3a8a7497bad2.gif)

このタグを装飾することでメニューの開閉をJavascriptなしで実現することが出来ます。
今回の例では`details > div`を`position: absolute`として、`box-shadow`で影を落とすことで、浮き出たメニューを表現しています。

detailsタグを使う以外にもJavascriptなしでこのような開閉メニューを作る方法あります。
見えないcheckboxを作って、checked属性の有無でスタイルを変更するというテクニックです。

しかし、checkboxはそう行った目的のタグではないため、メニューの開閉に使うというのは直感的ではありません。
details、summaryの方が表示の開閉をイメージしやすく直感的なためこちらの方が目的にあったタグだと考えます。
（対応ブラウザの話はさておいて）

## メニュー外をクリックした時にメニューが閉じる

detailsタグをそのまま使っただけでは、summary部分をクリックしない限り閉じてくれません。
GitHubでは、:beforeを使ったテクニックを使っていました。

![Nov-29-2019 23-54-28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/27fa3d7f-c7ce-93e1-f8c0-e7cc761ca9af.gif)

わかりやすくするために:beforeの要素を赤い半透明にしてみました。
メニュー外に透明な当たり判定用のパネルを広げているんですね。

:beforeを使わない場合は、Javascriptで処理を書かなければいけないと思いますが、
このやり方だとJavascriptなしでスッキリかけますね。


## デメリット

- detailsタグは、IE、EDGEで使えない
    - Polyfillがあるのでそれで対応したい
- 開閉のアニメーションが出来ない
    - Mozilla情報だと出来ないらしい（出来そうな気もする、未検証）
    - https://developer.mozilla.org/ja/docs/Web/HTML/Element/details
 <img width="686" alt="Screen Shot 2019-11-30 at 12.05.35 AM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/440677b1-bdd3-b44b-8f50-26d12a971644.png">

## まとめ

- GitHubのポップアップメニューはJavascriptなしで動いてすごい
- detailsタグ
    - HTML5.1で追加になった
    - 詳細折りたたみ要素
    - めっちゃいいけどIEとEDGE未対応
- 透明な:beforeをヒットボックスにするアイデアいいね