🪗

2025年末のdetails/summaryタグを使ったアコーディオンの現状

に公開

この記事は、mast Advent Calendar 2025 の2日目の記事です。
1日目はわたすけさんの記事「Linux の /proc/self/exe はどのように実行ファイルのパスを指すのか」でした。
https://adventar.org/calendars/11736

はじめに

Happy Advent! 知識情報・図書館学類のおかし(@oka4shi)です。
今年もアドベントカレンダーの季節がやってきましたね。
mastの友人がいる & 春日エリアのよしみで、mastに関係があると主張してmast Advent Calendarに参加したいと思います。

さて、今回の話題はdetailsタグ・summaryタグを使ったアコーディオンの実装についてです。
このテーマは自身の周辺で2025年にホットであり、しかも2025年から非常に使い勝手が良くなったので、アドベントカレンダーの記事としてまとめてみようと思います。

details/summaryタグとは?

そもそも、detailsタグ・summaryタグとはどんなものでしょうか?
まずはHTMLの仕様を示すHTML Living Standard[1]を確認してみましょう。

details要素は4.11.1で定義されています。最初の部分を確認してみると以下のように説明されています。

The details element represents a disclosure widget from which the user can obtain additional information or controls.
The first summary element child of the element, if any, represents the summary or legend of the details. If there is no child summary element, the user agent should provide its own legend (e.g. "Details").
The rest of the element's contents represents the additional information or controls.

日本語に翻訳してみるとこのような感じでしょうか。

details要素は、ユーザーが追加の情報やコントロールを得ることのできるディスクロージャーウィジェットを表す。
details要素の最初の子要素であるsummary要素が存在すれば、それはdetailsの概要、または説明文を表す。もし、子となるsummary要素がなければ、ユーザーエージェントは説明文を提供すべきである(例: "Details")。
要素の残りのコンテンツは追加の情報やコントロールを表す。

少し抽象的で難しいですが、概要を示し折りたたむことができて、中に詳しい内容を表示することができるような要素を表すことが分かります。これは、まさにアコーディオンに当てはまるのではないでしょうか。

具体例を見てみましょう。details/summaryタグは以下のように構成されます。

<details>
  <summary>詳細を見る</summary>
  <p>ここに詳しい内容が書かれています</p>
</details>

この場合、以下のような対応関係が見られます。

  1. 一番外側の<details>~</details>: "The details element"(details要素)
  2. その中にある<summary>詳細を見る</summary>: "The first summary element child of the element"(最初の子要素であるsummary要素)
  3. <p>ここに詳しい内容が書かれています</p>: "The rest of the element's contents"(要素の残りのコンテンツ)

details/summaryタグを使うメリット

さて、アコーディオンにdetailsタグおよびsummaryタグを使うと具体的に一体何が良いのでしょうか。
その答えとしては、主に次の2点に集約されると思っています。

  1. DOM構造がシンプルになり、スクリプトも不要になる
  2. 意味が明確になる(セマンティックになる)

従来の実装では、詳細コンテンツ部分はdisplay: none;などで隠しておき、概要部分をbutton要素などで実装し、そのクリックを検知してそのプロパティーをJavaScriptで付け替えるというアプローチが一般的だったかと思います。Reactなどのフレームワークを使うにせよ、ライブラリを探してきたり、スクリプトを書いたり、状態管理に気を配ったりという面倒なプロセスがありました。でも、details/summaryタグを使えばこの必要がなくなります。これが1のメリットです。
そして、2のメリットとしては、アクセシビリティーが向上する、検索エンジンにテキストが引っかかるようになる、ページ内検索が使えるようになるという点があります。特にページ内検索にヒットしたら自動でdetails要素の残りのコンテンツが表示されるというのは、従来の方法では不可能でした。

アニメーション周りの課題とその解消

このように便利なdetailsタグとsummaryタグを使ったアコーディオンですが、最近まで閉じる際のアニメーションが難しいという課題がありました。
閉じた瞬間にdetils要素のopen属性が消えてしまうため、CSSのTransitionが特に閉じる際にうまく動かない状況でした。そのため、完璧にアニメーションさせようとするならイベントをpreventDefault()して、JS側でハンドリングしたりアニメーションを発火させたりする必要があり、面倒でした。
また、Blinkには詳細部分(最初隠れている部分)を直接クラスで指定すると最初の1回しかアニメーションしないという不具合があり、CSSだけでアニメーションさせようとすると不安定という問題もあります。

しかし、::details-content疑似要素[2]の登場によってこの状況が改善されました。これは、details要素の「要素の残りのコンテンツ」部分を指す疑似要素です。これを使用することで、CSSのみで完璧なアニメーションを伴うアコーディオンを実装することができます。

ただ、長らくBlink (Chrome)のみに実装されているという部分が実際に使用するにはネックになっていました。しかし、ブラウザ間の互換性を改善するプロジェクトであるInteropの2025年の重点目標にも選ばれ、その結果WebKit (Safari)とGecko (Firefox)にもついに実装され、全モダンブラウザで使用できるようになりました。Firefoxでは143、Safariでは18.4から使用することができます。
https://caniuse.com/wf-details-content

details/summaryタグを使ったアコーディオンの実例

では実例を見てみましょう。以下がHTMLとCSSだけで実装したアコーディオンの例となります。

最新のブラウザを使っていれば、開くとき・閉じるときともにアニメーションができているはずです。

CSSでアコーディオンをアニメーションさせる限界

先程の例で、特に閉じるときに最後にガクっと動くのが気になった方もいるかもしれません。実はここに、現在CSSのTransitionの機能ではうまく実装できないまだ一つポイントが残されています。この現象の原因としては、Transitionでは高さを動的にアニメーションさせるられないという部分にあります。Transitionのアニメーションでは、固定値と固定値の間のアニメーションは可能なのですが、固定値とautoなどのキーワードの間のアニメーションのサポートは限定的となっています。interpolate-sizeプロパティによってこれが可能となりますが、現状ではBlink (Chrome)のみの実験的な機能となっていることが問題です。これがWebKit (Safari)やGecko (Firefox)によってもサポートされるようになれば、この高さのアニメーションという部分も改善されるでしょう。現状では、「要素の残りのコンテンツ」部分が開いたときの高さを固定値で指定する、details/summaryタグを使いつつアニメーションにはJavaScriptのライブラリを使う、Firefox・Safariで若干不格好になるのを許容する、などの手段で凌ぐしかありません。

https://caniuse.com/wf-interpolate-size

おわりに

2025年にブラウザが新しくサポートした::details-content疑似要素によって、details/summaryタグを使ったアコーディオンが実装しやすくなりました。特にアニメーション周りの問題が1つ解決したのは大きいでしょう。details/summaryタグには様々なメリットがあるので、積極的に活用していきたいものです。アコーディオンを実装する機会があれば、ぜひdetails/summaryタグを検討してみてください。一方、コンテンツ部分の高さのアニメーションが難しいという問題はまだ残されています。この部分が解決され、更にきれいなアコーディオンがCSSだけで実装できるようになる日はそう遠くないでしょう。
若干気が早いですが、皆さんが良いクリスマス・良い年末を送られることを祈っております。では、ここまでお読みいただきありがとうございました!

脚注
  1. 今回は2025年11月17日最終更新版を参照しました ↩︎

  2. 記事執筆時点(2025年12月1日)にはMDNにはまだ日本語版記事はないようです ↩︎

Discussion