WEB Tips デザイン・コーディング

クリックで開閉アコーディオンメニューの作成例 jQuery、CSSのみ

2014-03-02

本記事にはプロモーションが含まれています。

クリックで開閉アコーディオンメニューの作成例 jQuery、CSSのみ

スマホサイトで利用する機会の多いアコーディオンメニュー。スペースを節約しつつ、多くの情報を表示できるので、ウェブサイトやアプリのUIによく使われます。

この記事ではCSSのみで作るアコーディオンメニュー、jQueryでサクッと実装できるシンプルタイプ、jQueryに依存しないJavaScriptで作るアコーディオンメニューを作り方を実例を挙げて紹介します。

タブメニューの作り方はこちらの記事で説明しています。レスポンシブなタブメニュー CSS&JS -Tab UI

CSSのみで作るアコーディオンメニュー

JavaScriptを使わずにCSSだけで作るアコーディオン。input要素とlabel要素を使って、チェックボックスの状態に応じてコンテンツの表示・非表示を切り替えます。

checkboxを使ったアコーディオン

See the Pen Accordion CSSのみ checkbox by mixtaro (@mixtaro) on CodePen.

<div class="accordion">
  <input type="checkbox" id="acc01">
  <label for="acc01">アコーディオン1</label>
  <div class="acc-content">
    アコーディオン1 が開いた時のコンテンツ
  </div>
  <input type="checkbox" id="acc02">
  <label for="acc02">アコーディオン2</label>
  <div class="acc-content">
    アコーディオン2 が開いた時のコンテンツ
  </div>
  <input type="checkbox" id="acc03">
  <label for="acc03">アコーディオン3</label>
  <div class="acc-content">
    アコーディオン3 が開いた時のコンテンツ
  </div>
</div>

checkboxのid属性とlabelのfor属性はワンセットで同じ名前を入れておきます。

.accordion label {
  position: relative
  display: block;
  cursor: pointer;
}
.accordion input {
  position: absolute;
  left: -999em;
}
.accordion input:checked + label + .acc-content {
  max-height: 1000px;
  transition: max-height 0.4s ease-in-out;
}
.acc-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-in-out;
}

checkboxは表示させないのでposition:absoluteで枠外へ飛ばしておきます。

クリックした時に表示するコンテンツ.acc-contentは初期状態で表示しないようCSSで設定する必要があります。

display:none/display:blcokで表示、非表示を切り替えることも可能ですが、コンテンツの開閉をアニメーションさせたいのでdisplayプロパティは使わずにmax-height:0にしておきます。

checkboxがチェックされたら(input:checked.acc-contentが表示されるようにmax-heightに大きい値を指定します。

radioボタンを使ったアコーディオン

See the Pen Accordion CSSのみ radio by mixtaro (@mixtaro) on CodePen.

<div class="accordion">
  <input type="radio" id="acc01" name="accgroup">
  <label for="acc01">アコーディオン1</label>
  <div class="acc-content">
    アコーディオン1 が開いた時のコンテンツ
  </div>

  <input type="radio" id="acc02" name="accgroup">
  <label for="acc02">アコーディオン2</label>
  <div class="acc-content">
    アコーディオン2 が開いた時のコンテンツ
  </div>

  <input type="radio" id="acc03" name="accgroup">
  <label for="acc03">アコーディオン3</label>
  <div class="acc-content">
    アコーディオン3 が開いた時のコンテンツ
  </div>
</div>

HTMLはcheckboxの時とほぼ同じですがname属性に同じ名前を設定して連携させる必要があります。

checkboxを使ったアコーディオン
クリックすると全てコンテンツが開いた状態になる

radioを使ったアコーディオン
クリックしたコンテンツだけが開いた状態になる

PCではタブメニュー、スマホではアコーディオンになるレスポンシブメニュー

See the Pen Responsive Tabs/Accordion -only CSS/ by mixtaro (@mixtaro) on CodePen.

タブメニューの作り方はこちらの記事で説明しています。レスポンシブなタブメニュー CSS&JS -Tab UI

CSSだけでアコーディオンを実装するメリット・デメリット

メリット:表示速度が向上する

CSSのみの場合、ブラウザの読み込み時間が短縮されるためウェブページの表示速度が向上する場合があります。またサーバーの負荷を軽減することができます。

デメリット:複雑な動きはできない

CSSだけで同じlabelをクリックしてアコーディオンコンテンツを閉じることはできません。

CSSは現在の要素とその親、子、兄弟要素のスタイリングするだけです。同じlabelをクリックしてアコーディオンコンテンツの表示非表示を切り替えるためにはJavaScriptが必要になります。

jQueryで作るアコーディオンメニュー

jQueryを使ってアコーディオンを作成するメリットは数行のコードだけであれば簡単に実装できることです。さまざまなブラウザやデバイスに対応しているので、互換性の問題を心配する必要がありません。

jQueryのシンプルなアコーディオンメニュー(1)

dlタグで実装するアコーディオンメニュー。数行のスクリプトで動きが作れます。

See the Pen Untitled by mixtaro (@mixtaro) on CodePen.

<dl>
  <dt>アコーディオン1</dt>
  <dd>アコーディオン1の中身</dd>
  <dt>アコーディオン2</dt>
  <dd>アコーディオン2の中身</dd>
  <dt>アコーディオン3</dt>
  <dd>アコーディオン3の中身</dd>
</dl>

jQueryを読み込んだ後に以下のコードを記述します。

$(function(){
   $("dt").on("click", function(){
      $(this).next().slideToggle();
      $(this).toggleClass("active");
   });
});

$(this).next().slideToggle()は、クリックされたdt要素の次の要素を選択して、スライドトグルアニメーションを適用して表示または非表示にします。

$(this).toggleClass("active")は、dt要素のactiveクラスを切り替えます。これにより、アクティブなアコーディオンコンテンツを指定します。

初期状態ではアコーディオン内のコンテンツを非表示にするため、CSSでdisplay:noneを指定しています。

dd {
  display: none;
}

jQueryのシンプルなアコーディオンメニュー(2)

例1では CSSでアコーディオンコンテンツの要素を非表示にしていますが、JavaScriptが無効の状態だった場合、アコーディオンコンテンツは非表示のままになってしまいます。

こちらの例では表示非表示もjQueryで制御することで、JavaScriptが使えない場合はアコーディオンコンテンツは全て表示されることになります。

See the Pen jQuery Accordion by mixtaro (@mixtaro) on CodePen.

<div class="accordion">
  <div class="accordion-item">
    <h3>アコーディオン タイトル</h3>
    <div class="answer">
      <p>アコーディオン コンテンツ</p>
    </div>
  </div>
</div>
$(function(){
  $(".accordion-item .answer").hide();

  $(".accordion-item h3").on("click", function(){
    var $answer = $(this).next(".answer");
    $answer.slideToggle();
    $(this).toggleClass("active");

  });
});

まず全てのアコーディオンコンテンツを非表示にし、クリックイベントが発生したときに、クリックされたアコーディオンタイトル(h3)に隣接するアコーディオンコンテンツのみを取得し、slideToggleメソッドで表示/非表示を切り替えます。

また、アコーディオンタイトルにactiveクラスを追加することで、アコーディオンが開いていることをユーザーに分かるようにCSSなどで加工することができます。

jQueryでアコーディオンを実装するメリット・デメリット

メリット:設置が簡単

数行で簡単に設置でき、ブラウザ間の互換性が高いのでブラウザごとに対応状況を心配する必要がありません。

デメリット:パフォーマンス低下

jQueryを読み込む必要があるので外部ファイルが必要になります。また、パフォーマンスが低下する可能性があります。

依存関係なしJavaScriptのアコーディオン

外部のライブラリやフレームワークに依存しない純粋なJavaScriptのコードで作るアコーディオンです。

ライブラリやフレームワークを使わずに、純粋なJavaScriptでアコーディオンを実装できるのでページの読み込み速度やパフォーマンスに影響を与えないというメリットがあります。

See the Pen accordion nav -js by mixtaro (@mixtaro) on CodePen.

このコードではaria-expanded属性が追加され、trueまたはfalseの値でアコーディオンアイテムが開かれたかどうかを示します。また、クリックされたアイテム以外のすべてのアイテムが閉じられ、クリックされたアイテムだけが開かれます。

aria属性は、アクセシビリティの向上に役立ちます。

ユーザーがスクリーンリーダーを使用してWebページを閲覧する場合、aria-expanded属性は、スクリーンリーダーのユーザーがアコーディオンメニューの開閉状態を理解できるようにします。

.acdmenu dd {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
.acdmenu dt[aria-expanded=true] + dd {
  max-height: 1000px;
  transition: max-height 0.3s ease-out;
}

max-heighttransitionを使用して、アコーディオンが開閉する際にアニメーションさせます。

アコーディオンが閉じているときは、max-height: 0で高さを0に設定し、transitionでアニメーションのタイミングを指定します。アコーディオンが開いているときは、max-heightに適当な値を設定して高さを開くようにします。

最初の要素は開いた状態のアコーディオン

See the Pen accordion 最初は開く by mixtaro (@mixtaro) on CodePen.

// 最初の li 要素を開く
firstAccordionItem.setAttribute('aria-expanded', true);
const firstUl = firstAccordionItem.querySelector('ul');
if (firstUl) {
  firstUl.style.display = 'block';
}

基本的には同じコードですが最初のli要素を開くように指定しています。

依存関係なしJavaScriptのアコーディオンを実装するメリット・デメリット

メリット:追加ファイル不要

外部のライブラリやフレームワークを読み込む必要がなく、アコーディオンに自由な動きをつけることができます。最近のモダンブラウザでは高速に実行されます。

デメリット:コード量が多くなる

jQueryを使用する場合に比べてコードが多くなり実装が複雑になる可能性があります。

以上、クリックで開閉アコーディオンメニューをCSSのみ、jQuery、JavaScriptで作るサンプルをまとめました。

それぞれの方法のメリットとデメリットも併せて掲載しておりますので、用途や好みに応じて使い分けてください。

タブメニューの作り方はこちらの記事で説明しています。レスポンシブなタブメニュー CSS&JS -Tab UI

今月キャンペーン特典があるサービス

  • エックスサーバー
    利用料最大30%キャッシュバッグ月額693円&ドメイン永久無料 - 2024年5月1日(水)12:00まで
  • ConoHa WING
    WINGパック36ヶ月で月額678円 53%OFF ドメイン2個無料 - 2024年4月19日(金)16:00まで
  • カラフルボックス
    ドメイン永久無料特典とBOX2以上の月額費用が50%OFFのクーポンコード「SERVER50

-WEB Tips, デザイン・コーディング
-, , ,