この記事では「素のJavaScriptを使ったアコーディオンメニューの作り方」について解説します。
アコーディオンメニューを取り入れれば、クリックしたりタップしたりすることでコンテンツを開閉させて情報の表示・非表示を切り替えることができます。
Webサイトでよく使用されるパーツの1つなので作り方を覚えておきましょう。
- JavaScriptを使ったアコーディオンメニューの作り方
jQueryでアコーディオンメニューを作る方法は下記の記事をご覧ください。
JavaScriptが難しくて挫折しそうなあなたへJavaScriptは独学で進めると難しい内容も多いですよね。相談相手がいないと煮詰まってしまうこともあるかと思います。
もし学習の進め方について悩まれているならば、ZeroPlusの無料相談会への参加をお勧めします。
ZeroPlusはWeb制作のフリーランス育成に特化したプログラミングスクールです。超フレンドリーなメンターがあなたの疑問や悩みについて、なんでもお答えします。
\お申し込みは30秒で終わります。/
学習方法の悩み、私たちと一緒に解消しましょう!
アコーディオンメニューとは、クリック時に項目を表示させる機能
アコーディオンメニューとは、クリック時に項目を表示させる機能のことです。クリック・タップするだけで情報の表示・非表示を素早く切り替えることができます。
アコーディオンメニューのメリットは、膨大な情報やコンテンツでもメニュー内に格納しておける点にあります。
サンプルコードは下記のとおりです。動きを確認してみましょう。
See the Pen Untitled by ZeroPlus (@zeroplus-programming) on CodePen.
アコーディオンのタイトル部分(青背景)をクリックすると、格納されていたコンテンツ部分が表示されます。その際に、矢印は下から上に方向が変わります。
JavaScriptでアコーディオンメニューを実装するポイント
この記事で紹介するアコーディオンメニュー実装のポイントは下記のとおりです。
アコーディオンメニュー実装ポイント
- アコーディオンのコンテンツ表示時、非表示時の状態をHTMLと、CSSで先に作る
- コンテンツの表示・非表示は、JavaScriptによるクラスのを付け外しで行う
機能を実装する場合、上記のように機能を細かく分解して実装するのがポイントです。
JavaSciptでアコーディオンメニューを実装してみよう!
ここからは具体的にJavaScriptを使ってアコーディオンメニューを実装していきます。
HTMLとCSSで表示時のアコーディオンメニューを作る
最初に、HTMLとCSSでアコーディオンメニューが表示された状態を作成します。
コードは下記のとおりです。
なお「qa」というクラス名は、よくある質問というコンテンツをアコーディオンメニューで表現することが多いので、今回はよくある質問のQuestion・Answerにちなんで命名しています。(クラス名は任意のものでOK)
<div class="qa">
<ul class="qa__block">
<li class="qa__item">
<button class="qa__head js-ac">テキストテキストテキストテキスト</button>
<div class="qa__body">
<p>
テキストテキストテキストテキスト
</p>
</div>
</li>
</ul>
</div>
.qa__block {
display: flex;
flex-direction: column;
min-width: 200px;
}
.qa__item {
display: inline-block;
}
.qa__head {
position: relative;
text-align: left;
padding: 20px 30px 20px 20px;
border-radius: 8px 8px 0 0;
background: lightblue;
color: black;
cursor: pointer;
width: 100%;
}
.qa__body {
position: relative;
border-radius: 0 0 8px 8px;
background: #fff;
color: black;
border: 1px solid lightblue;
padding: 20px;
}
出力結果
項目のタイトル部分(青い部分)はbuttonタグで作成します。
クリックしたらアコーディオンメニューが開くようにJavaScriptで制御したいので、qa__head要素にjs-acクラスを付与しておきます。
HTMLとCSSでアコーディオンメニューの矢印をつくる
矢印は下記のように疑似要素で作成します。
.qa__head:after {
content: "";
border-top: 1px solid black;
border-left: 1px solid black;
display: inline-block;
width: 10px;
height: 10px;
transform: rotate(-135deg) translateY(9px);
position: absolute;
right: 20px;
top: 50%;
}
出力結果
矢印が作成できました。矢印はborderプロパティで作成し、transform: rotate(-135deg);
で回転させています。
HTMLとCSSで非表示時のアコーディオンメニューを作る
アコーディオンメニューの本文部分(白背景)を非表示にする場合、qa__body要素は下記のようなコードになります。
.qa__body {
position: relative;
border-radius: 0 0 8px 8px;
background: #fff;
color: black;
border: transparent; /*borderを非表示の状態にする*/
padding: 0 20px; /*上下のpaddingを0に書き換える*/
line-height: 0; /* 非表示時、0*/
opacity: 0; /* 非表示時、0*/
}
出力結果
qa__body要素の上下paddingを0、line-heightを0にしています。さらにopactiy: 0;
でqa__bodyのコンテンツ部分を非表示にします。
これでアコーディオンメニュー非表示時の状態が作成できました。
HTMLとCSSで表示時のアコーディオンメニューを作る(クラス付与時)
qa__body要素にis-openクラスを付与して、is-openクラスが付いたときだけアコーディオンメニューが表示されるようにします。また、qa__head要素にis-openクラスを付与したときだけ矢印が上向きになるようにします。
コードは下記のようになります。
<li class="qa__item">
<!-- is-open 付与 -->
<button class="qa__head is-open js-ac">テキストテキストテキストテキスト</button>
<!-- is-open 付与 -->
<div class="qa__body is-open">
<p>
テキストテキストテキストテキスト
</p>
</div>
</li>
.qa__body.is-open {
padding: 20px;
line-height: 1.5;
opacity: 1;
border: 1px solid lightblue;
}
.qa__head.is-open::after {
transform: rotate(45deg) translateY(-10px);
}
出力結果
qa__body要素にis-openクラスが付いたとき、上下のpaddingを20px、line-height:1.5;
、opacity: 1;
、border: 1px solid lightblue;
にします。
矢印は、qa__headにis-openクラスが付いたとき、上向きになるように調整します。
JavaScirptでアコーディオンメニューを制御する
アコーディオンメニューのタイトル部分をクリックしたらqa__head要素とqa__body要素にis-openクラスが付与されるように、JavaScriptで下記のコードを記述します。
const qa = document.querySelector(".js-ac"); // js-ac要素を取得し変数に格納
function acToggle() { // クリック時に発火する関数を作成
const content = this.nextElementSibling; // js-ac要素の「次の要素」を取得し変数に格納
content.classList.toggle("is-open"); // js-ac要素の「次の要素」
const qa = this; // js-ac要素自身を変数に格納
qa.classList.toggle('is-open'); // js-ac要素にis-openつけ外し
}
qa.addEventListener("click", acToggle);// クリックイベントを登録、acToggle関数を発火
出力結果
アコーディオンメニューのタイトル部分をクリックすると、アコーディオンメニューが開閉します。
nextElementSibling は指定した要素の「次の要素」を取得するプロパティです。
変数 contentは、js-acクラスが付いた要素の次の要素であるqa__body要素を格納しています。
<li class="qa__item">
<!-- クリックした要素 -->
<button class="qa__head js-ac">テキストテキストテキストテキスト</button>
<!-- クリックした要素の「次の要素」 -->
<div class="qa__body">
<p>テキストテキストテキストテキスト</p>
</div>
</li>
クラスの付け外しは、下記のclassList.toggleで行っています。
// qa__body要素にis-openクラスの付け外し
content.classList.toggle("is-open");
const qa = this;
// js-ac要素にis-openクラスの付け外し
qa.classList.toggle('is-open');
アコーディオンメニューがふわっと開閉するアニメーションを追加する
現状では、アコーディオンメニューはパッと開閉する状態です。これをふわっと開閉するような動作にする場合、CSSに下記のように追記します。
.qa__head:after {
content: "";
border-top: 1px solid black;
border-left: 1px solid black;
display: inline-block;
width: 10px;
height: 10px;
transform: rotate(-135deg) translateY(9px);
position: absolute;
right: 20px;
top: 50%;
/* 追記 */
transition: transform .4s;
}
.qa__body {
position: relative;
border-radius: 0 0 8px 8px;
background: #fff;
color: black;
border: transparent;
padding: 0 20px;
line-height: 0;
opacity: 0;
/* 追記 */
transition: line-height 0.4s, padding 0.4s, opacity 0.4s;
}
出力結果
メニューがふわっと開閉するようになりました。transitionを設定する場合は、どのプロパティに対してtransitionを設定するのか、明示的に示しましょう。
アコーディオンメニューが複数ある場合
現状では、アコーディオンメニューが複数ある場合、クリックしても2つ目以降のアコーディオンメニューは開閉しません。
(なお、CSSでアコーディオンメニュー間の余白を下記のように調整します)
.qa__item:not(:first-child) {
margin-top: 16px;
}
アコーディオンメニューが複数ある場合でも開閉できるように、JavaScriptを書き換えます。
const qa = document.querySelectorAll(".js-ac"); // js-ac要素すべて取得
function acToggle() {
const content = this.nextElementSibling;
content.classList.toggle("is-open");
const qa = this;
qa.classList.toggle('is-open');
}
for (let i = 0; i < qa.length; i++) { // for文でjs-acメニューをループ処理
qa[i].addEventListener("click", acToggle);
}
出力結果
アコーディオンメニューの数だけfor文でループ処理を行い、クリックしたアコーディオンメニューに対してis-openクラスを付け外しするように、クリックイベントを発火させます。
for文のループ処理に関しては、下記の記事をご覧ください。
アコーディオンを実装するときは、ひとつひとつの動きを確認する
JavaScriptでアコーディオンを実装する方法について解説しました。アコーディオンメニューは情報の出し入れをすばやく行うことができます。情報の量が多くても、コンパクトに格納しておけるのが、アコーディオンメニューの最大のメリットです。
実際に手を動かして実装してみましょう。
Web制作は、その他にも学ぶべき知識が数多くあります。
Web制作初学者がWeb制作を学習するにあたって、押さえておくべき知識・技術は「Web制作学習ロードマップ」の記事にまとめています。どこまで勉強すればいいか分からない、次はどんなスキルを勉強すればいいか分からない、という方はぜひ参考にしてみてください!
JavaScriptを使ったアコーディオンメニューまとめ
- コンテンツの表示、非表示をクリック1つで素早く切り替えることができる
- コンテンツの情報が多くても、アコーディオンメニュー内に格納しておける
- JavaScriptでCSSのクラスを付け外しすることで、メニューの表示・非表示を切り替える
- ふわっとした動きをつけるためには、CSSにtransitionを指定する
プログラミング学習でこのような経験はありませんか?
- 目標に向けて何を学べば良いかわからない
- 調べても解決策が見つからない
- 現場レベルのスキルが身につくのか不安
これらの悩みは、学習環境を整えることで全て解決することができます。
ZeroPlus Gateでは、30日間無料で最適な学習環境を提供しています。
- なんでも相談できる専属メンター
- いつでも技術相談ができるプロ講師
- 元IT企業CTO監修のカリキュラム
条件なしでこのレベルの環境を無料で提供しているのはZeroPlus Gateだけです。
ただし、無料サービスの提供には参加者の数に制限があります。
少しでも興味がある方は、以下のリンクからサービスの詳細をご覧ください。