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

クリックするとアニメーションしながら開閉する折りたたみ要素の実装方法です。
いくつかの方法がありますが、<details>(詳細折りたたみ要素)とJavaScriptを使って実現する方法がメリットも多く最もおすすめです。

【推奨】 <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というクラス名を付けています。

具体的には.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にまとめたほうが良いかもしれません。

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

<details>要素とCSSのみでの展開アニメーションは不安定

CSSによる装飾とアニメーション

CSSのみでは高さを取得できませんがline-heightを使うことで展開される部分の高さをアニメーションさせています。高さを指定しないのでコンテンツ量に応じた高さまで伸びて止まります。

この場合、opacityline-heightと時間差をつけないと効果が体感できないので注意です。

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

2022.08.31現在、open属性の有無を元にしたCSSのみのアニメーションではアニメーションする場合としない場合があるようです。閉じる際のアニメーションは効きません。
今後改善されることを期待しています──。

jQuery(きっかけのみ)とCSSによるアコーディオン

開閉のきっかけをjQueryで行う

jQueryのtoggleClass()を使ってクラス名の追加と削除のみ行っています。
toggleClass()は指定の要素に任意のクラス名が無ければ付与し、既にある場合は削除するメソッドです。

jQueryとCSSで行う開閉アニメーション

toggleClass()で付与するクラス名.activeの有無によって適用するCSSを切り替えています。
右端の三角アイコンもCSSで再現してみました。

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

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

slideToggle()の使い方

slideToggle()は実行される度に指定の要素が開閉するjQueryメソッドです。
数行のjQueryで簡単に実装できるので便利ですが、実際には連続して変形させる重めの処理を行っています。

後述のtoggleClass()と合わせてCSSアニメーションと組み合わせることもできます。

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

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

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

<details>をslideToggle()で動かそうとするとうまく動きません──。
初回の動作が不安定であったり、閉じる際にアニメーションしない場合があるようです。
それ以外の要素の場合はslideToggle()が使えます。

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

チェックボックスで開閉状態を切り替える

<input type="checkbox">を使って開閉状態を切り替えます。
CSSの疑似クラス:checkedを使ってチェックボックスがオフの場合は閉じた状態、オンの場合は開いた状態のスタイルを定義しています。

チェックボックスとCSSによるアニメーション

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

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

それぞれの特徴やメリット・デメリット等

  • <details>とJavaScript【推奨】
    HTML構造を把握しやすい専用要素でメリットも多い。開閉アニメーションはJavaScriptで実現。
  • <details>とCSS
    <details>要素のopen属性の有無を元にしたCSSのみでのアニメーションは不安定。今のところ出番は無さそう。
  • jQueryきっかけとCSS
    汎用性が高く負荷も少ない。
  • slideToggle()
    手っ取り早く設置できるが今回の中では一番重い。<details>要素との組み合わせは不安定なため他の要素を使う必要あり。
  • checkboxとCSS
    アニメーションはCSSのみなので一番軽量。HTMLが複雑になり分かりにくい。

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