##はじめに
最近ポートフォリオサイトのコードを書き換えていたのですが、今までjQueryで書いていたアコーディオンメニューを、CSSのみで割と簡単に実装できたので、記事に残しておこうと思います。
##作るもの
アコーディオンメニュー
→webサイトのQ&A欄とかでよく使われるやつです。一応デモ画像貼っときます。
##コード
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="style.css" />
<title>Document</title>
</head>
<body>
<input id="check1" type="checkbox" class="acd-check" />
<label class="check-label" for="check1">質問文</label>
<div class="acd-content">
<p>
答え
</p>
</div>
<input id="check2" type="checkbox" class="acd-check" />
<label class="check-label" for="check2">質問文 </label>
<div class="acd-content">
<p>
答え
</p>
</div>
<input id="check3" type="checkbox" class="acd-check" />
<label class="check-label" for="check3">質問文</label>
<div class="acd-content">
<p>
答え
</p>
</div>
</body>
</html>
CSS
p {
margin: 0;
}
.acd-check {
display: none;
}
.check-label,
.acd-content {
width: 800px;
font-size: 14px;
max-width: 100%;
width: 800px;
margin: 0 auto 2px auto;
background: #00bcd4;
color: #fff;
}
.check-label {
position: relative;
display: block;
padding: 10px;
user-select: none;
cursor:pointer;
}
.check-label::after {
position: absolute;
top: 10px;
right: 10px;
content: "+";
}
.acd-content {
height: 0;
opacity: 0;
padding: 0 10px;
transition: 0.3s;
}
.acd-check:checked + .check-label + .acd-content {
display: flex;
background: #16a085;
align-items: center;
height: 40px;
opacity: 1;
}
.acd-check:checked + .check-label::after {
content: "-";
font-size: 16px;
}
##仕組み
####全体の仕組み
このコードでは、アコーディオン開閉の挙動をinputタグのチェックボックスを使って操作しています。質問文がチェックボックスのラベルになっていて、ラベルをクリックするとチェックボックスにチェックが入るという仕組みです。
試しにacd-checkのdisplay:noneをコメントアウトしてみるとわかりやすいかと思います。
アニメーション部分はopacity(透明度の操作)を使っています。チェックされていない時の透明度が0、チェックされた時を1として、この間の変化を0.3秒で行うように設定します。
####個人的に分かりずらかった部分
.acd-check:checked + .check-label + .acd-content {
display: flex;
background: #16a085;
align-items: center;
height: 40px;
opacity: 1;
}
この部分。今まで隣接セレクタ(+)を使うことがなかったので少し混乱しました。
.acd-check(チェックボックス)がチェックされた時の.acd-content(答え)に適用させるCSSを書いてるのに、+ check-labelてなんなんだ...。関係なくない?みたいな感じで。
.acd-check:checked + .acd-content{
/* 上と同じ */
}
こうじゃないの?と思ったんですが、これじゃダメみたいです。
+は 隣接セレクタという名前の通り、同一階層の直後にある要素にしか適用できない。つまり、HTMLを確認すると、 .acd-checkの直後には .acd-labelがあるから、(イメージとしては)まずここに移動してからその直後にある.acd-contentに適用するってわけなんですね。
##終わりに
元々はjQueryで書いていた部分をVue.jsに変えるつもりで始めた作業だったんですが、そもそもCSSだけで実装できるってことが結構多くて驚きました。CSSすごい。
というわけで、この記事はここまでになります。ありがとうございました。