【コピペOK】CSSだけでアコーディオンメニューを作る方法

項目の多いメニューやよくある質問等で利用することの多いアコーディオンメニューを、CSSだけで作る方法の紹介です。

コピペするだけで、
・アニメーションでの開閉
・閉じている時はプラス(+)アイコン
・開いている時はマイナス(ー)にアニメーションする
アコーディオンメニューを実装できます。

DEMO

この記事の目次

  1. HTML
  2. CSS

HTML

閉じている状態をチェックボックとして設定し、
クリックされた時(チェックされた時)に、アニメーションで隠れている内容を表示するという仕組みです。

<div class="accordion">

<div class="option">
<input type="checkbox" id="toggle1" class="toggle">
<label class="title" for="toggle1">タイトル1</label>
<div class="content">
<p>本文1</p>
</div>
</div>

<div class="option">
<input type="checkbox" id="toggle2" class="toggle">
<label class="title" for="toggle2">タイトル2</label>
<div class="content">
<p>本文2</p>
</div>
</div>

<div class="option">
<input type="checkbox" id="toggle3" class="toggle">
<label class="title" for="toggle3">タイトル3</label>
<div class="content">
<p>本文3</p>
</div>
</div>

</div>

CSS

.accordion {
margin: 3em auto;
max-width: 60vw;
}
.toggle {
display: none;
}
.option {
position: relative;
margin-bottom: 1em;
}
.title,
.content {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform: translateZ(0);
transition: all 0.3s;
}
.title {
border: solid 1px #ccc;
padding: 1em;
display: block;
color: #333;
font-weight: bold;
}
.title::after,
.title::before {
content: "";
position: absolute;
right: 1.25em;
top: 1.25em;
width: 2px;
height: 0.75em;
background-color: #999;
transition: all 0.3s;
}
.title::after {
transform: rotate(90deg);
}
.content {
max-height: 0;
overflow: hidden;
}
.content p {
margin: 0;
padding: 0.5em 1em 1em;
font-size: 0.9em;
line-height: 1.5;
}
.toggle:checked + .title + .content {
max-height: 500px;
transition: all 1.5s;
}
.toggle:checked + .title::before {
transform: rotate(90deg) !important;
}

CSS解説

17行目
展開した内容を閉じる時の速度

26〜36行目
プラスアイコンの基本となる線の設定。
色・サイズ・場所・アニメーション速度等を指定しています。
::beforeと::afterで2本設定し、
38行目で1本だけ90度倒しプラスにしています。

51〜52行目
展開した時の最大の高さと展開する速度を指定しています。
高さより内容量が多い場合は、はみ出た分は表示されません。

55行目
展開した時にプラスボタンの縦棒を90度倒してマイナスに見える様にしています。

プラス(+)からマイナス(ー)へのアニメーションではなく、
プラス(+)からバツ(X)へのアニメーションにしたい場合は以下の様に角度をつけます。

.toggle:checked + .title::before {
transform: rotate(45deg) !important;
}
.toggle:checked + .title::after {
transform: rotate(135deg) !important;
}