<div class="container">
<details class="details">
<summary class="summary">質問</summary>
<div class="answer">
<div class="answerInner">回答</div>
</div>
</details>
<br />
<details class="details">
<summary class="summary">質問</summary>
<div class="answer">
<div class="answerInner">回答</div>
</div>
</details>
<br />
<details class="details">
<summary class="summary">質問</summary>
<div class="answer">
<div class="answerInner">回答</div>
</div>
</details>
</div>
.container {
background-color: lightblue;
min-height: 100vh;
padding: 40px;
}
.list {
display: grid;
row-gap: 20px;
padding: 20px;
}
/* ここまで調整用スタイル */
.details {
background-color: white;
}
.summary {
cursor: pointer;
font-weight: bold;
padding: 20px;
}
.answer {
overflow: hidden;
}
.answerInner {
padding: 0 20px 20px;
}
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".details").forEach(function (el) {
const summary = el.querySelector(".summary");
const answer = el.querySelector(".answer");
summary.addEventListener("click", (event) => {
// デフォルトの挙動を無効化
event.preventDefault();
// detailsのopen属性を判定
if (el.getAttribute("open") !== null) {
// アコーディオンを閉じるときの処理
const closingAnim = answer.animate(closingAnimation(answer), animTiming);
closingAnim.onfinish = () => {
// アニメーションの完了後にopen属性を取り除く
el.removeAttribute("open");
};
} else {
// open属性を付与
el.setAttribute("open", "true");
// アコーディオンを開くときの処理
const openingAnim = answer.animate(openingAnimation(answer), animTiming);
}
});
});
});
// アニメーションの時間とイージング
const animTiming = {
duration: 300,
easing: "ease-in-out",
};
// アコーディオンを閉じるときのキーフレーム
const closingAnimation = (answer) => [
{
height: answer.offsetHeight + "px",
opacity: 1,
},
{
height: 0,
opacity: 0,
},
];
// アコーディオンを開くときのキーフレーム
const openingAnimation = (answer) => [
{
height: 0,
opacity: 0,
},
{
height: answer.offsetHeight + "px",
opacity: 1,
},
];
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.