🪗

detailsタグとsummaryタグで実装しよう!アコーディオン(開閉アニメーションつきサンプルあり)

2022/07/04に公開1
アコーディオンとは?

こういうの。
最初は見出しのみが表示されていて、クリックすると中のコンテンツが表示されるような折りたたみ要素。

detailsタグ、summaryタグとは?

  • 以下のように記述することで、クリックによる開閉が ブラウザによって(JS要らずで)動作する HTMLタグ。
<details open>
    <summary>アコーディオンとは?</summary>
    <p>こういうの。<br>最初は見出しのみが表示されていて、クリックすると中のコンテンツが表示されるような折りたたみ要素。</p>
</details>
  • HTML 5.1 で勧告され、現在は HTML Living Standard で標準となっている、比較的新しいHTMLタグ。
    • 主要ブラウザ(もちろんIEを除く)では問題なく使用できる。
  • 最初に示した Zenn の折りたたみ要素もこれらのタグで表示されている。
  • detailsタグのopen属性の有無で開閉状態を示す。

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

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

サンプル

divタグ、buttonタグのみで表現したアコーディオンの実装と、
detailsタグ、summaryタグで実装したアコーディオンのサンプルを用意しました。
どちらも機能には変わりがなく、ただ方法が異なるのみです。

details, summaryを使うメリット

  • JSが必要ない
    • 上記のサンプルではアニメーションを実装するためにJSを使用していますが、アニメーションが必要なければブラウザが開閉処理を行ってくれるため、JSが不要です。
  • セマンティクス(要素の意味)を表現できる。
  • アクセシビリティ対応もできる

実装のポイント

CSS

  • ブラウザデフォルトのスタイルにより、 「▼」(三角マーク) が表示される。
    • この三角は、 display: list-item (つまり、箇条書きリストの「●」(丸)と同じプロパティ)によって表示される。
    • ただし、Safariにおいては、display: list-itemではなく、::-webkit-details-marker 擬似要素によって表示される。
    • よって、三角マークを非表示にするためには、以下の2つの指定が必要になる。
summary {
  list-style: none;
}
summary::-webkit-details-marker {
  display: none;
}
  • summaryをホバーしてもポインター(指さしマーク)にならないため、以下を指定するとよい。
summary {
  cursor: pointer;
}
  • 開閉状態によってスタイルを変化させる場合は、 details[open] で区別する。
    • なお、JSでアニメーションを付ける場合はopenの付くタイミングがずれてしまう。この対策のため、上記サンプルでは閉じるためのクリック後に data-accordion-before-close という属性をつけることで、クリック直後にも閉じてた状態のスタイルを当てられるように調整している。

JS

  • 閉じるときのアニメーション をつけるためには、summaryのクリックイベントをpreventDefault()して、アニメーション完了後にopen属性を付与する必要がある。

    • 要素が非表示になってしまうと、アニメーションのさせようがないため。
  • detailsの開閉時には、toggle イベントが発生する。開閉時になにかを行いたい場合に使用できる。

まとめ

実装が楽になり、かつアクセシビリティの質も向上できる、 details タグ、 summary タグをぜひ使っていきましょう!

参考記事

https://code-kitchen.dev/html/details-summary/

GitHubで編集を提案

Discussion

pessopesso

gsapを使えば、detailsタグとsummaryタグで実装したアコーディオンでも、
heightを0からautoにできるんですね!凄く勉強になりました!