スマホサイトで利用する機会の多いアコーディオンメニュー。スペースを節約しつつ、多くの情報を表示できるので、ウェブサイトやアプリの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属性に同じ名前を設定して連携させる必要があります。
PCではタブメニュー、スマホではアコーディオンになるレスポンシブメニュー
See the Pen Responsive Tabs/Accordion -only CSS/ by mixtaro (@mixtaro) on CodePen.
タブメニューの作り方はこちらの記事で説明しています。レスポンシブなタブメニュー CSS&JS -Tab UI
CSSだけでアコーディオンを実装するメリット・デメリット
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でアコーディオンを実装するメリット・デメリット
依存関係なし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-height
とtransition
を使用して、アコーディオンが開閉する際にアニメーションさせます。
アコーディオンが閉じているときは、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のアコーディオンを実装するメリット・デメリット
以上、クリックで開閉アコーディオンメニューをCSSのみ、jQuery、JavaScriptで作るサンプルをまとめました。
それぞれの方法のメリットとデメリットも併せて掲載しておりますので、用途や好みに応じて使い分けてください。
タブメニューの作り方はこちらの記事で説明しています。レスポンシブなタブメニュー CSS&JS -Tab UI