SEARCH

CATEGORY

[JavaScript] button要素で作るアコーディオン|スムーズな開閉を実装する方法

本記事では、button 要素とJavaScript(Vanilla JS)を使い、スムーズに開閉するアコーディオンの実装方法を紹介します。

button 要素を使用することでアクセシビリティにも配慮でき、Chrome・Edge・Firefox・Safariなど主要ブラウザでも安定して動作します。

シンプルなアコーディオンのデモ

まずは完成イメージです。
以下のCodePenでは、JavaScript(Vanilla JS)で実装したスムーズなアコーディオンを確認できます。

CodePen デモ

[JavaScript] button要素で作るスムーズなアコーディオン

See the Pen [JavaScript] button要素で作るスムーズなアコーディオン by mkl may (@mkl-may) on CodePen.

HTML

アコーディオンの見出しにはbutton要素を使用します。

クリックによる開閉操作を行うUIのため、意味を持たない div 要素ではなく、操作を目的とした button 要素を使用することで、HTMLの意味付け(セマンティクス)的にも適切な実装になります。

また、button要素はキーボード操作やスクリーンリーダーにも標準対応しているため、アクセシビリティの観点からも推奨されています。

CSS

初期状態ではコンテンツ部分の高さを0にし、overflow: hidden; を指定して内容を非表示にします。

JavaScriptで max-height を切り替えることで、高さが滑らかに変化するアコーディオンを実装しています。

また、矢印アイコンには擬似要素を使用し、開閉状態に応じて回転するよう設定しています。

JavaScript

JavaScriptでは、見出しのbutton要素がクリックされた際にactiveクラスを付け外ししています。

また、開閉状態に応じてmax-height を動的に変更することで、滑らかなアニメーションを実現しています。
開く場合は scrollHeight でコンテンツの実際の高さを取得し、その値を max-height へ設定します。
閉じる場合は max-height をリセットすることで、高さが0へ向かってアニメーションします。

jQueryの slideDown()slideUp() を使用しなくても、シンプルなコードで滑らかな開閉アニメーションを実装できます。

複雑なコンテンツ向けの実装

コンテンツ内に複数段落・画像・ボタンなどを含む場合は、
.accordion-content-inner を追加して親子構造にすることで、
アニメーションを担当する .accordion-content と、
レイアウトを担当する .accordion-content-inner を分離できます。

CodePen デモ

[JavaScript] button要素で作るスムーズなアコーディオン(.accordion-content-inner版)

See the Pen [JavaScript] button要素で作るスムーズなアコーディオン(.accordion-content-inner版) by mkl may (@mkl-may) on CodePen.

HTML

CSS

inner要素を分けることで、 高さアニメーションとコンテンツ演出を分離できます。

aria-expanded に対応してアクセシビリティを向上する

アクセシビリティをさらに向上させる場合は、aria-expanded を追加することで、スクリーンリーダー利用者にも開閉状態を伝えられます。

CodePen デモ

[JavaScript] button要素で作るスムーズなアコーディオン(.accordion-content-inner + aria-expanded 版)

See the Pen [JavaScript] button要素で作るスムーズなアコーディオン(.accordion-content-inner + aria-expanded 版) by mkl may (@mkl-may) on CodePen.

HTML

JavaScript

button要素を使用する理由

アコーディオンの見出し部分は「押すことで状態が変化する操作ボタン」です。

そのため、以下のようなdiv要素で実装するよりも、

<div class="accordion-header">
  Question
</div>

button要素を使用する方が本来の目的に沿ったマークアップになります。

<button class="accordion-header" type="button">
  Question
</button>

button要素には次のようなメリットがあります。

  • キーボード(Enterキー、Spaceキー)で操作できる
  • スクリーンリーダーでボタンとして認識される
  • アクセシビリティ向上につながる
  • HTMLの意味付けとして適切

details / summaryとの違い

アコーディオンは details 要素と summary 要素でも実装できます。

<details>
  <summary>Question</summary>
  <p>Answer</p>
</details>

details要素はHTMLだけで開閉機能を実現できるため非常に便利ですが、高さを滑らかにアニメーションさせることが難しいという特徴があります。

また、ブラウザごとにアニメーションの実装方法や挙動差を考慮する必要がある場合もあり、スムーズな開閉を重視する場合は button 要素とJavaScriptを組み合わせた実装の方が扱いやすいケースが多くあります。

用途に応じて使い分けるとよいでしょう。

まとめ

今回は、button要素とJavaScript(Vanilla JS)を使ったスムーズなアコーディオンの実装方法を紹介しました。

button要素を使用することでアクセシビリティにも配慮でき、Chrome・Edge・Firefox・Safariなど主要ブラウザでも安定して動作します。

jQueryを使わずに軽量かつアクセシブルなアコーディオンを実装したい場合は、ぜひ活用してみてください。