<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,
  },
];

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.