Help us understand the problem. What is going on with this article?

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

概要

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

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

Nov-29-2019 22-44-08.gif
図 マイページのコンテキスト切り替えメニュー

Nov-29-2019 22-27-24.gif
図 プルリクエストページのプロジェクト選択メニュー

なにが優れてる?

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

サンプルコード

https://codepen.io/y-tsuzaki/pen/abzoOgL

Nov-29-2019 23-05-14.gif

<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タグをみてみましょう

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

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

detailssummaryは,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

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

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

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

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

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

Nov-29-2019 23-54-28.gif

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

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

デメリット

まとめ

  • GitHubのポップアップメニューはJavascriptなしで動いてすごい
  • detailsタグ
    • HTML5.1で追加になった
    • 詳細折りたたみ要素
    • めっちゃいいけどIEとEDGE未対応
  • 透明な:beforeをヒットボックスにするアイデアいいね
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away