Q&Aなどに使える、アコーディオンの作り方2種類
![](https://nori-portfolio.com/wp-content/uploads/2021/12/accordion-menu_01.jpg)
Q&Aなどでよく使われる、アコーディオンを作っていきたいと思います!
アコーディオンメニュー1
実装目標の確認
-
質問1
答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え
-
質問2
答え
-
質問3
答え
HTML & CSS & JavaScript コード例
<ul>
<li>
<h3 class="question1">質問</h3>
<p class="answer1">答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え</p>
</li>
<li>
<h3 class="question1">質問</h3>
<p class="answer1">答え</p>
</li>
<li>
<h3 class="question1">質問</h3>
<p class="answer1">答え</p>
</li>
</ul>
クラス名をquestion1
、answer1
としているのは、あとからもう1パターン紹介する都合上なので、question2
、question3
と数字を変えずに同じクラス名で統一してください。
/* 質問 */
.question1 {
background-color: #F0D290;
border-radius: 5px;
padding: 5px;
cursor: pointer;
margin-top: 10px;
position: relative;
}
/* アイコン(閉じている時=プラスマーク) */
.question1::before, .question1::after {
content: "";
width: 10px;
height: 2px;
background-color: #333;
position: absolute;
top: 50%;
right: 10px;
}
.question1::before {
transform: translateY(-50%);
}
.question1::after {
transform: translateY(-50%) rotate(90deg);
}
/* アイコン(開いている時=マイナスマーク) */
.question1.open::after {
display: none;
}
/* 答え */
.answer1 {
padding: 10px;
display: none;
}
/* 答え(開いている時) */
.answer1.open {
display: block;
}
const questions1 = document.querySelectorAll('.question1');
for(let i = 0; i < questions1.length; i++) {
questions1[i].addEventListener('click', function(e) {
e.target.classList.toggle('open');
e.target.nextElementSibling.classList.toggle('open');
});
}
アコーディオンメニュー2
実装目標の確認
-
質問
答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え
-
質問
答え
-
質問
答え
HTML & CSS & JavaScript コード例
<ul>
<li>
<h3 class="question2">質問</h3>
<div class="answer2"><p class="text">答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え答え</p></div>
</li>
<li>
<h3 class="question2">質問</h3>
<div class="answer2"><p class="text">答え</p></div>
</li>
<li>
<h3 class="question2">質問</h3>
<div class="answer2"><p class="text">答え</p></div>
</li>
</ul>
パターン1と同じ理由でクラス名に番号を付けています。
また、パターン2ではanswer2
にpadding
を付けるときれいに隠れないので、中に<p></p>
を作ってそちらにpadding
を当てるようにします。
/* 質問 */
.question2 {
background-color: #F0D290;
border-radius: 5px;
padding: 5px;
cursor: pointer;
margin-top: 10px;
position: relative;
}
/* アイコン(閉じている時=プラスマーク) */
.question2::before, .question2::after {
content: "";
width: 10px;
height: 2px;
background-color: #333;
position: absolute;
top: 50%;
right: 10px;
transition: .3s;
}
.question2::before {
transform: translateY(-50%);
}
.question2::after {
transform: translateY(-50%) rotate(90deg);
}
/* アイコン(開いている時=マイナスマーク) */
.question2.open::after {
transform: translateY(-50%) rotate(180deg);
}
/* 答え(閉じている時) */
.answer2 {
overflow: hidden;
height: 0;
transition: height .3s ease-out;
}
.text {
padding: 10px;
}
const questions = document.querySelectorAll('.question2');
for(let i = 0; i < questions.length; i++) {
questions[i].addEventListener('click', function(e) {
let targetAnswer = e.target.nextElementSibling;
// 答えが開いている場合
if (targetAnswer.style.height) {
targetAnswer.style.height = null;
e.target.classList.remove('open');
// 答えが閉じている場合
} else {
targetAnswer.style.height = targetAnswer.scrollHeight + 'px';
e.target.classList.add('open');
}
});
}
まとめ
いかがでしたか?
アコーディオンメニューはよく見かけるので、マスターしておきたいですね。
最後までご覧いただきありがとうございました。