クリックで開閉するアニメーション付きアコーディオン【CSS/JavaScript/jQuery】

クリックするとアニメーションしながら開閉する折りたたみ要素の実装方法です。
今回は主に<details>(詳細折りたたみ要素)とJavaScriptを使って実現する方法を紹介します。

他の方法と比較してメリットも多いのでぜひ使ってみてください。

PR

【推奨】<details>要素をJavaScriptでアニメーションさせる方法

<details>(詳細折りたたみ要素)とは

<details>は「詳細折りたたみ要素」と呼ばれるHTML5で追加された要素で、HTMLのみでも開閉可能な「詳細説明」を表しています。

子要素に<summary>で概要(ラベル)を指定し、続けて詳細説明を書きます。概要(ラベル)は省略することができ、省略した場合多くのブラウザでは「詳細」と表示されます。

初期状態では閉じていますが<details open>のようにopen属性を付けると最初から開いた状態で表示されます。

See the Pen Untitled by web-souko (@web-souko) on CodePen.

参考リンク
MDN Web Docs – <details>: 詳細折りたたみ要素

<details>要素を使うメリット

  • HTMLタグだけで詳細折りたたみ要素と分かるためソースの可読性も良い。
  • Tab移動やEnterによる開閉等、キーボード操作にも標準で対応。
  • 閉じていてもページ内検索の対象となる。

JavaScriptで開閉動作にアニメーションを付ける

<details>要素の開閉動作はCSSアニメーションではうまく動かないため、ここはJavaScriptで補います。

今回は開閉部分を<div>で囲い、.details__contentというクラス名を付けています。この要素に対してJavaScriptでWeb Animations APIを操作してアニメーションさせます。

See the Pen Accordion animation – JS by web-souko (@web-souko) on CodePen.

参考リンク
MDN Web Docs – ウェブアニメーション API

回転する三角アイコンはCSSのみでアニメーションさせていますが、動きに関する部分を分離するという観点ではJavaScriptにまとめたほうが良いかもしれません。

PR

その他の方法で実現するアコーディオンアニメーション

<details>要素のopen属性をきっかけにしたCSSアニメーションは不安定

開いたときに付与されるopen属性の有無でCSSアニメーションさせようという方法ですが、この方法はうまく動きません(2023.02.28現在)。

アニメーションする場合としない場合があり、閉じる際のアニメーションは効きません。今後改善されることを期待して一応CSSの紹介だけしておきます。

CSSのみでは高さを取得できませんがline-heightを使うことで展開される部分の高さをアニメーションさせています。高さを指定しないのでコンテンツ量に応じた高さまで伸びて止まります。この場合、opacityline-heightと時間差をつけないと効果が体感できないので注意です。

See the Pen Accordion details + animation by web-souko (@web-souko) on CodePen.

jQueryで付与したクラス名とCSSによるアコーディオン

open属性をきっかけにしたCSSアニメーションではうまく動かないため、jQueryのtoggleClass()を使って付与したクラス名をきっかけにしたパターンですが、<details>要素ではうまく動きません。しかし<details>以外の要素を動かす場合は有効なため一応紹介しておきます。

toggleClass()は指定の要素に任意のクラス名が無ければ付与し、既にある場合は削除するメソッドです。toggleClass()で付与するクラス名.activeの有無によって適用するCSSを切り替えています。右端の三角アイコンもCSSで再現してみました。

See the Pen Accordion animation – jQuery+CSS by web-souko (@web-souko) on CodePen.

jQueryのslideToggle()を使ったアコーディオン

実行される度に指定の要素が開閉するjQueryメソッドのslideToggle()を使う方法ですが、<details>要素ではうまく動かないため、その他の要素を使った場合の例を紹介します。

この方法は数行のjQueryで簡単に実装できるので便利ですが、実際には連続して変形させる重めの処理を行っています。toggleClass()と合わせてCSSアニメーションと組み合わせることもできます。

次のデモでは、ラベル.details__summaryがクリックされる度にラベル直後の要素.details__contentに対してslideToggle()が実行されます。最低限のアコーディオンアニメーションであればこれだけで実現できます。

See the Pen Accordion details + animation by web-souko (@web-souko) on CodePen.

チェックボックスとCSSで実現するアコーディオン

項目ごとに用意したチェックボックスの状態によって開閉状態を切り替える方法です。

CSSの疑似クラス:checkedを使ってチェックボックスがオフの場合は閉じた状態、オンの場合は開いた状態のスタイルを用意しています。

input[type=checkbox]:checked + 〇 + △のように直後の要素を表す兄弟セレクターと組み合わせることで、該当する要素のみアニメーションするようにしています。

See the Pen Accordion animation – jQuery+CSS by web-souko (@web-souko) on CodePen.

実装方法による特徴やメリット・デメリット等のまとめ

<details>とJavaScriptによるアニメーション

  • HTML構造を把握しやすい専用要素
  • Tab移動やEnterで開閉等のキーボード操作に対応
  • 閉じていてもページ検索の対象となる
  • 開閉アニメーションはJavaScriptで実現

<details>とCSSのみでのアニメーション

  • open属性の有無をトリガーにしたCSSのみでのアニメーションは不安定
  • うまく動作しないので今のところ出番は無さそう

jQueryで付与したクラス名をきっかけにしたCSSアニメーション

  • <details>以外の要素では有効
  • 汎用性が高く負荷も少ない
  • <details>要素ではCSSのみの場合と同様に不安定

jQueryのslideToggle()によるアニメーション

  • 手っ取り早く設置可能
  • 処理内容は重め
  • <details>要素では意図した動きにならない

checkboxとCSSでのアニメーション

  • アニメーションはCSSのみなので軽量
  • HTMLが複雑になり分かりにくい
  • <details>要素ではうまく動かない

実装方法の違いによる特徴をまとめてみました。

<details>要素が持つデフォルトの開閉動作とCSSでのアニメーションの組み合わせは相性が悪いようですが、JavaScriptのpreventDefault()で既定の動作を行わないようにすると問題なくアニメーションできるようになりました。

他の要素と比べてメリットの多い<details>要素をぜひ採用したいところです。

最後まで読んでいただきありがとうございました。


PR

タイトルとURLをコピーしました