jQueryでアコーディオンメニューをサクッと作ろう【コピペOK】

jQueryでアコーディオンメニューをサクッと作ろう【コピペOK】

この記事を書いた人

だいち

PENGIN BLOGメディア編集長。Web業界とは異業種の仕事をしながら、独学でWeb制作の世界に。副業でHP制作やコーディング代行、個人ブログの運営などに取り組み、現在はPENGINにてWebライティングやディレクションをしつつ、メディア運営全般を担当しています。(個人運営ブログ:https://daib-log.com/ )

Webサイトを作成するうえで「アコーディオンメニュー」という汎用的なUIパーツがありますが、jQueryを活用して実装するケースが多いです。

基礎的なメソッドを知っておけば簡単に作ることができるので、この記事ではアコーディオンメニューの簡単な実装方法をコード付きで解説します。

記事を読み終えると、アコーディオンメニューの実装方法が一通り理解でき、使い回しできるコードを知ることができますよ!

jQueryでアコーディオンメニューを作ろう

アコーディオンメニューとは

アコーディオンメニューとは、Webページなどの表示・操作要素の一つで、選択した項目がその場で広がって詳細な内容を表示する形式のメニューのこと。限られた範囲で多数の項目を一覧でき、かつ詳細な内容を即座に参照できるメニュー形式として利便性が高い。

アコーディオンメニューとは – IT用語辞典 e-Words

以下のサンプルを見て、実際のアコーディオンメニューのイメージをつかみましょう!

メニュー①
メニュー①の中身
メニュー②
メニュー②の中身
メニュー③
メニュー③の中身
メニュー④
メニュー④の中身

HTML/CSSの記述

まずはHTMLのコードから。

<dl class="ac">
    <dt class="ac-parent">メニュー</dt>
    <dd class="ac-child">メニューの中身</dd>
    <dt class="ac-parent">メニュー</dt>
    <dd class="ac-child">メニューの中身</dd>
    <dt class="ac-parent">メニュー</dt>
    <dd class="ac-child">メニューの中身</dd>
    <dt class="ac-parent">メニュー</dt>
    <dd class="ac-child">メニューの中身</dd>
  </dl>

accordion-parentはクリック領域、accordion-childはクリックされた際に展開される領域です。
HTMLタグはクリック(タップ)する領域と、オープンする領域があれば別のタグでも問題ありません。

しかし、アコーディオンはQ&Aなど定義と説明がセットになっているセクションに多く活用されますので、上記のようにdl タグを使うなど、コンテンツの意味に沿ったタグを選択するようにしましょう。

次にCSSです。

/* リセットCSS */
* {
  list-style: none;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* アコーディオンメニュー全体のサイズ・位置 */
.ac {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

/* クリック領域 */
.ac-parent {
  height: 50px;
  border-bottom: 1px solid #fff;
  background-color: #f97148;
  color: #fff;
  text-align: center;
  line-height: 50px;
  cursor: pointer;
}

/* クリックしたら表示される領域 */
.ac-child {
  display: none;
  padding: 2em 1em;
  background-color: #ffccbc;
  text-align: center;
}
Image from Gyazo

ac-childは初め非表示にしておきたいので、display: noneを指定しています。
(※画像はわかりやすいようにac-childが全て展開されている状態のものです)

非表示の指定はjQueryでもできますが、今回はjQuery側をなるべく簡潔にするためCSSの方で記述しています。

jQueryの記述

次にjQuery全体のコードです。

$(function () {
    $('.ac-parent').on('click', function () {
    $(this).next().slideToggle();
  });
});

これだけです!とてもシンプルですね!

jQueryの基本的な書き方

$(function(){~~~~});

基本的な構文は上記の通りで、~の中に内容を記述していきます。

今回は.ac-parentをon click(クリック)したら、this(その要素)のnext(次の要素)がslideToggleする、という内容になっています。

この中でも今回は重要なslideToggleについて解説を入れていきます。

slideToggleの使い方

slideToggleは、toggleClass、fadeToggle と同様、toggle系メソッドに分類されます。

いずれも指定される対象や、要素に与える影響に違いはありますが、基本的な考えは動作のONとOFFを切り替えるスイッチのようなメソッドです。

アコーディオンメニューのように状態のON・OFFを切り替えるUIにはこのtoggle系メソッドが活躍します。基本のtoggleメソッド自体は、指定された要素の表示と非表示を切り替える機能を有していて、例えば、

//cssメソッド
$(this).css(‘display’,’none’)
→ $(this).css(‘display’,’block’)

//hide、showメソッド
$(this).hide();
→ $(this).show();

これらの内容を

$(this).toggle();

この一行で済ますことができます。

そして今回使うslideToggleメソッドは、slideDownメソッドとslideUpメソッドの動作を交互に行う機能を有しています。

DownとUpを切り替える「スイッチ」代わりになるメソッド、とイメージしてもらえれば分かりやすいかと思います。

「もし、〇〇の要素が表示されていなければスライドダウンで表示させ、表示されていればスライドアップで隠す」という内容をslideToggleメソッドを使わない場合下記コードになります。

$(function () {
  $('#toggleIcon').on('click', function () {
    if ($(this).next().css('display') == 'none') {
      $(this).next().slideDown();
    } else {
      $(this).next().slideUp();
    }
  });
});

これをslideToggleメソッドを使った記述にすると

$(function () {
  $('#toggleIcon').on('click', function () {
    $(this).next().slideToggle();
  });
});

これだけで済みます!

Image from Gyazo

かなりシンプルなコードで上の画像の動きを表現できるので、かなり便利なメソッドだということが分かりますよね!

ここまででアコーディオンメニューの実装に必要なjQueryの仕組みが分かったかと思います!

応用① 矢印アイコンでアコーディオンメニューの開閉状態を明示する

Image from Gyazo

CSSの記述

※HTMLは上述と同じです。

CSSはac-parentクラスのみ変更を加ます。

.ac-parent {
	position: relative;  /* 追加 */
	height: 50px;
	border-bottom: 1px solid #fff;
	background-color: #f97148;
	color: #fff;
	text-align: center;
	line-height: 50px;
	cursor: pointer;
}

/* 擬似要素で下三角形を作成 */
.ac-parent:after {
	content: "";
	display: inline-block;
	position: absolute;
	top: 45%;
	right: 30px;
	width: 10px;
	height: 10px;
	border-right: 3px solid #fff;
	border-bottom: 3px solid #fff;
	transform: translateY(-50%) rotate(45deg);
	transition: .3s;
}

/* オープン時にopenクラスを付与 */
.ac-parent.open:after {
	transform: rotate(225deg);
}

矢印アイコンは扱いやすいように擬似要素で作成しています。

jQueryでopenクラスを付与した際には、擬似要素の矢印を逆方向に回転させています。

jQueryの記述

$(function () {
  $('.ac-parent').on('click', function () {
    $(this).next().slideToggle();
    //openクラスをつける
    $(this).toggleClass("open");
    //クリックされていないac-parentのopenクラスを取る
    $('.ac-parent').not(this).removeClass('open');

    // 一つ開くと他は閉じるように
    $('.ac-parent').not($(this)).next('.ac-child').slideUp();
  });
});

新たに追記した内容について個別に見ていきましょう。

$(this).toggleClass('open');

toggleClassメソッドを使い「open」というクラスを付与しています。

toggleClassメソッドは、要素に対して指定したclassの有無を判定し、つけ外ししてくれるメソッドです。()内につけ外ししたいクラス名を記述します。

cssで用意していた、openクラスを付与した状態のスタイルと切り替わります。

$('.ac-parent').not(this).removeClass('open');

クリックされていない要素からはopenというクラスを外す、という記述です。

not(this)で対象でない要素を指定し、removeClass(‘open’)でopenクラスを外します。

Image from Gyazo

ちょっと分かりづらいかもしれませんが、上記の記述がない場合、このようにイベントで付与するクラスが意図しない要素についた状態となってしまいます。

$('.ac-parent').not($(this)).next('.ac-child').slideUp();

開いているメニューと違う要素がクリックされたらスライドアップで閉じる、という内容です。
上記でクリックされていない要素のopenクラスは外すようにしましたが、これはクリックされていないメニューは閉じている状態を想定しているからです。
一つ開いたら他は閉じるようにしないと、アイコンとメニューの開閉状態にズレが生じてしまうのでこの記述が必要になります。
not($(this))で対象でない要素を指定し、その次のaccordion-childクラスはスライドアップする、という内容です。

この「一つ開いたら他は閉じる」というアコーディオンメニューの仕様は、一般的なので使い回しできるように理解しておきたいです。

応用② プラス/マイナスアイコンでアコーディオンメニューの開閉状態を明示する

Image from Gyazo

CSSの記述

※HTMLは上述と同じです。
CSSはac-parentクラスのみ変更を加ます。

.ac-parent {
	position: relative;  /* 追加 */
	height: 50px;
	border-bottom: 1px solid #fff;
	background-color: #f97148;
	color: #fff;
	text-align: center;
	line-height: 50px;
	cursor: pointer;
}

/* ①プラスの横線 */
.ac-parent:before {
	content: "";
	position: absolute;
	top: 50%;
	right: 8px;
	width: 24px;
	height: 2px;
	background: #fff;
	transform: translateY(-50%);
}

/* ②プラスの縦線 */
.ac-parent:after {
	content: "";
	position: absolute;
	top: 50%;
	/* 8px+12px-1px(幅2pxの半分) */
	right: 19px;
	width: 2px;
	height: 24px;
	background: #fff;
	transform: translateY(-50%);
	transition: .3s;
}

/* ③オープン時にopenクラスを付与(縦線を回転させて非表示に) */
.ac-parent.open:after {
	top: 25%;
	opacity: 0;
	transform: rotate(90deg);
}

それぞれ擬似要素の①beforeでプラスの縦線、②afterで横線を作っています。

③では②のafterにjQueryでopenクラスを付与した状態のスタイルを記述しています。

Image from Gyazo

jQueryの記述

$(function () {
  $('.ac-parent').on('click', function () {
    $(this).next().slideToggle();
    //openクラスをつける
    $(this).toggleClass("open");
    //クリックされていないac-parentのopenクラスを取る
    $('.ac-parent').not(this).removeClass('open');

    // 一つ開くと他は閉じるように
    $('.ac-parent').not($(this)).next('.ac-child').slideUp();
  });
});

jQueryは先ほどの応用①で記述したコードと全く同じ内容で完成します!

ユーザーフレンドリーな実装を!

アコーディオンメニューは、クリックされるまでコンテンツが隠されているUIです。
ユーザーに対して「クリックできるメニューであること」「メニューは開いているのか閉じているのか」が分かりやすい作りになっている必要があります。

アコーディオンメニューの開閉状態をアイコンで明示する

メニューに対してクリックできる要素かどうかというのは、意外とわかりづらいものです。

そこで、矢印や+アイコンなど、一般的にクリック操作を促していることがわかるアイコンを仕様して、直感的にメニューが開けることを理解できる実装を心掛けましょう。

展開できるとわかる見た目にする

アコーディオンメニューは他要素とスタイルに差をつけて、目立つようにしておくことも重要です。

周りのデザインと同化していると、アイコンなど装飾があったとしても、ユーザーに対して操作を促すパーツだと認識されずらくなります。

クリックしたら展開される、独立した要素だとわかるように色や枠線なども工夫が必要です。

何が表示されるかわかりやすい見出しにする

クリックされる要素に何が展開されるか明確にしておくことも重要です。

Q&AだとQ(question)にあたる見出しや、内容に対するタイトルなど、ユーザーがクリックして中身を見た際にギャップを感じないよう、わかりやすい見出しにしておきましょう。

まとめ

アコーディオンメニューはWebサイトにはよく採用されるデザインなのでしっかり使いこなせるようにしておきましょう!

その他にも汎用的なUIをまとめたカテゴリもあるので、色んな記事を見て回ってくれると嬉しいです!