こんにちは、ナカムラです。
今回はdetailsについて試してみたものをご紹介したいと思います。
よくある質問などでよくアコーディオンを使うと思います。
たくさんある中でユーザーが求めている物・そうでないものがあるので、必要な時だけ開くようにするのが目的です。
そんなアコーディオンの作り方は色々ありまして、JavaScriptで開閉させるものと、CSSだけで制御するものなどが主流でした。
私も上記のどちらかを使っています。
detailsを活用したいと思っていますが、実務で使う場合は開閉する際にアニメーションをつけたいので結局従来のやり方で作ってしまっています。
簡単にアニメーションをつける方法がないものか模索中です。
detailsとは?
HTMLの「詳細折りたたみ要素」をマークアップするタグです。 developer.mozilla.org
<details> <summary>見出し</summary> 折り畳まれる詳細 </details>
これだけでアコーディオンになります。
とても簡単ですが、そのままではアニメーションはつきません。
DEMO
実際に見てみましょう。
書いたのは下記の4種類になります。
- HTMLだけの状態
- HTMLだけの状態:最初から開いた状態にする
- 開くときにアニメーションする:CSSのみ
- 開くときにアニメーションする:JavaScriptを使用
See the Pen jsもinputもいらないHTMLタグだけのアコーディオン<details> by Nakamura (@takayo-nakamura) on CodePen.
HTMLだけの状態
まずはHTMLの状態です。
見出しの背景にはアニメーションをつけているので動いている風に見えますが、折り畳まれた詳細はただの表示・非表示になります。
詳細が1〜2行程度のコンテンツならこれで十分かもしれません。
HTMLだけの状態:最初から開いた状態にする
ページを表示したときに表示した状態にしておきたい場合もあります。
detailsにopenをつけておけばOKです。
開くときにアニメーションする:CSSのみ
開かれた時はopen属性がつくので、それを利用して装飾などの変化をつけることができます。
しかし、何度かクリックを繰り返すとアニメーションしないタイミングも出てきてしまいます。
開くときにアニメーションする:JavaScriptを使用
ステータスのタイミングの問題ならば、自分でつけてしまえ。
ということでJavaScriptに頼りました。ちょっと悔しい…。
今回はリファレンスにあるtoggleを使いました。
const animationItem = document.querySelector('.js-animation') animationItem.addEventListener("toggle", (event) => { if (animationItem.open) { animationItem.classList.add('is-open') } else { animationItem.classList.remove('is-open') } });
要素を取得して、変化したとき(toggle)にopenかどうかで判定しています。
あとはステータスを表すクラスを付け外し、それを対象にスタイルを付けます。(スタイル自体はCSSのみの時と同じです)
最後に
気づいた方もいるかと思いますが、今回作ったアニメーションはスライドではありません。
detailsの表示/非表示は要素の表示/非表示になるため、高さの変化をつけるにはJavaScriptであらかじめ要素の高さを取得し、付与する必要があります。
閉じるときにもアニメーションをつけたい場合もJavaScriptで制御します。
スライドするアニメーションについて詳しく書いてくださっている記事がありますので、こちらをお読みください。
detailsとsummaryタグで作るアコーディオンUI - アニメーションのより良い実装方法 - ICS MEDIA