今回はJavaScriptとCSSでアコーディオンメニューを作っていきたいと思います。
完成形はこんな感じです。

アコーディオンメニューの作成
今回のファイル構成です。全部同じディレクトリにあります。
- index.html
- style.css
- scripts.jsindex.htmlファイルの作成
まず、index.htmlファイルを用意して、style.cssとscripts.jsを読み込みます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>アコーディオンメニュー</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<nav id="menu">
<div class="accordion">
犬の種類
<div class="symbol"><span></span><span></span></div>
</div>
<ul class="panel">
<li><a href="#">トイプードル</a></li>
<li><a href="#">チワワ</a></li>
<li><a href="#">柴犬</a></li>
<li><a href="#">ポメラニアン</a></li>
<li><a href="#">ブルドッグ</a></li>
</ul>
<div class="accordion">
猫の種類
<div class="symbol"><span></span><span></span></div>
</div>
<ul class="panel">
<li><a href="#">スコティッシュフォールド</a></li>
<li><a href="#">マンチカン</a></li>
<li><a href="#">アメリカンショートヘア</a></li>
<li><a href="#">ラグドール</a></li>
<li><a href="#">ロシアンブルー</a></li>
</ul>
<div class="accordion">
鳥の種類
<div class="symbol"><span></span><span></span></div>
</div>
<ul class="panel">
<li><a href="#">セキセイインコ</a></li>
<li><a href="#">文鳥</a></li>
<li><a href="#">コザクラインコ</a></li>
<li><a href="#">オカメインコ</a></li>
<li><a href="#">ヨウム</a></li>
</ul>
</nav>
<section id="main"><h1 id="title">メインコンテンツ</h1></section>
<script src="scripts.js"></script>
</body>
</html>
bodyタグの直下に<nav id=”menu”>と <section id=”main”>を置いて、navにはアコーディオンメニューを、sectionにはメインコンテンツを置くというレイアウトです。
後でレスポンシブ対応も行います。
アコーディオンメニュー内では、<div class=”accordion”>の部分をクリックすると<ul class=”panel”>内のメニューが展開する予定です。
<div class=”symbol”>は、アコーディオンが展開によって+とーが切り替わるようにします。
コードをまとめて出していますが、実際にはCSSやJavaScriptと同時に編集しています。
style.cssファイルの作成
index.htmlと同じディレクトリにstyle.cssを作成して、コードを書きます。
まずはレイアウトとアコーディオン部分です。
@import url("https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;700&display=swap");
body {
display: flex;
margin: 0;
font-family: "Zen Maru Gothic", sans-serif;
}
a {
color: #dba39a;
text-decoration: none;
}
#main {
width: 100%;
background-color: #fefcf3;
color: #dba39a;
display: flex;
justify-content: center;
align-items: center;
min-height: 600px;
}
#menu {
min-width: 250px;
}
@media screen and (max-width: 600px) {
body {
flex-wrap: wrap;
}
#menu {
width: 100%;
}
}
.accordion {
background-color: #f5ebe0;
color: #dba39a;
cursor: pointer;
padding: 18px;
border: none;
display: flex;
justify-content: space-between;
align-items: center;
}
.panel {
list-style-type: none;
margin: 0;
padding: 0 18px;
background-color: #fefcf3;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease;
}
.panel li {
margin: 10px;
}フォントは、Google fontsのZen Maru Gothicを使っています。
bodyでdisplay: flex;にして、メニュー部分とメインコンテンツを横に並べています。
画面幅が600px以下になると、bodyの flex-wrap: wrap; で、メニュー部分とメインコンテンツの並びが縦になります。
アコーディオンのクリックできる部分(.accordion)は、cursor: pointer;にしてクリッカブルだということを明示しています。
アコーディオンの展開する部分(.panel)は、いったんmax-height: 0;と、overflow: hidden;で見えないように隠しています。後でJavaScriptで、max-heightの数値を変更します。
transitionの記述はアニメーションの設定です。
あとは、全体的に余白だったり色だったりを調整しています。
scripts.jsの作成
次はJavaScript部分の記述に入っていきます。
同じディレクトリにscripts.jsを作成してコードを書きます。
const accordions = document.getElementsByClassName("accordion");
for (let i = 0; i < accordions.length; i++) {
accordions[i].addEventListener("click", function () {
this.classList.toggle("active");
const panel = this.nextElementSibling;
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}まず、.accordionから複数の要素を取り出して、accordionsに収めます。ちなみに複数なのでsをつけています。
forループを使って、取り出したaccordionsの要素ひとつずつにイベントリスナーを付与していきます。
function() {}のthisは、この場合、accordion[0]とかaccordion[1]とかに当たります。
クリックされたら.accordionのクラスリストに”active”をつけたり外したりします。
これは後の+ーマークの切り替えで使います。
変数panelは、thisのnextElementSibling、つまりclass=”accordion”の弟(or妹)要素のことを示しています。
class=”panel”のことですね。

次のif文では、panelのstyleのmax-heightが指定されていればそれをnullにして、そうでなければmax-heightを指定しています。CSSのインライン記述のstyle=”max-height: 〇〇px”のことです。
scrollHeightと言うのは、隠れている部分も含めての要素の高さのプロパティです。それに単位のpxをつけてmax-heightを指定しています。
ちなみにCSSのmax-heightはJavaScripではmaxHeightと書きます。
アコーディオン動作の確認
ではここまでの動きを見てみましょう。

きちんとアコーディオンメニューが動作していますね。
次はプラス・マイナスマークを作成します。
プラス・マイナスのマークの作成
すでにindex.htmlには、class=”symbol”の下にspanタグを2つ用意しているので、これに対してCSSで形や動きを作っていきます。
形を作る
style.cssに下記を追記します。
.symbol {
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.symbol span {
display: block;
background-color: #dba39a;
width: 100%;
height: 1px;
transition: all 0.4s ease;
}
.symbol span:nth-of-type(1) {
transform: translateX(15px);
}
.symbol span:nth-of-type(2) {
transform: rotate(-90deg);
}.symbolは縦横30pxの正方形で、中身はflex-boxを使って要素を縦横中央に揃えています。
中身のspanは1pxの細さの線です。この時点では2本ともただの横棒ですね。
nth-of-type(1)で1本めの線を指定して、右に15px移動。
nth-of-type(2)で2本目の線を指定して、-90度回転。
これでプラスマークができました。

動きを作る
次はアコーディオンが開いたときには2本の線が重なって、マイナスになるようにしたいところです。
scripts.jsで記述したように、アコーディオンが開いているときには、.accordionのクラスリストに”active”が追加されるのでこれを利用します。
先程のCSSの下に下記コードを追記します。
.accordion.active .symbol span:nth-of-type(2) {
transform: rotate(0deg);
}.accordionが”active”のときに、その下の.symbolの下の、2個めのspanを指定して、回転を0度に戻しています。
これで2本の線が重なってマイナスになります。

こんな感じでアコーディオンメニューができました。
Codepenを貼っておきます
最後にCodepenを貼っておきます。
レスポンシブでレイアウトが変わります。600pxがブレークポイントです。
See the Pen Untitled by tkyytnm (@tkyytnm) on CodePen.
以上です。ご参考になれば。


コメント