JSFiddle - React, Tailwind, and code Playground

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<h1 style="text-align: center;">JavaScript 系列三:練習5 ── collapse 折疊效果</h1>

<div class="FAQ">
  <div class="Q-box">
    <p class="Q" onclick="collapse()">如何辦理退換貨?
      <span class="icon">
        <i class="fa-solid fa-plus positive active"></i>
        <i class="fa-solid fa-minus negative"></i>
      </span>
    </p>
    <p class="A">請參考退貨服務頁面。</p>
  </div>
  <div class="Q-box">
    <p class="Q" onclick="collapse()">退款方式及退款時間?
      <span class="icon">
        <i class="fa-solid fa-plus positive active"></i>
        <i class="fa-solid fa-minus negative"></i>
      </span>
    </p>
    <p class="A">約7-8個工作天完成退款作業。</p>
  </div>
  <div class="Q-box">
    <p class="Q" onclick="collapse()">未退回的退款,是否可直接折抵新訂單?
      <span class="icon">
        <i class="fa-solid fa-plus positive active"></i>
        <i class="fa-solid fa-minus negative"></i>
      </span>
    </p>
    <p class="A">很抱歉,重新訂購時無法直接於新訂單扣抵。</p>
  </div>
  <div class="Q-box">
    <p class="Q" onclick="collapse()">發票遺失是否仍能辦理退換貨?
      <span class="icon">
        <i class="fa-solid fa-plus positive active"></i>
        <i class="fa-solid fa-minus negative"></i>
      </span>
    </p>
    <p class="A">很抱歉,需要有發票才能辦理退換貨。</p>
  </div>
  <div class="Q-box">
    <p class="Q" onclick="collapse()">什麼情況無法辦理退換貨?
      <span class="icon">
        <i class="fa-solid fa-plus positive active"></i>
        <i class="fa-solid fa-minus negative"></i>
      </span>
    </p>
    <p class="A">超過7天退貨期限,就無法辦理。</p>
  </div>
</div>

CSS

* {
  padding: 0;
  margin: 0;
}

.FAQ {
  width: 600px;
  padding: 20px;
  box-sizing: border-box;
  margin: auto;
  border-radius: 10px;
}

.Q-box {
  width: 100%;
  margin: auto;
  box-sizing: border-box;
}

.Q-box+.Q-box {
  margin-top: 20px;
}

.Q-box .Q {
  display: flex;
  padding: 10px;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  background-color: #fff;
  transition: 0.5s;
}

.Q-box .Q.active {
  background-color: #eee;
}

.Q-box .Q:hover {
  background-color: #eee;
}

.Q-box .A {
  box-sizing: border-box;
  height: 0;
  overflow: hidden;
  padding: 10px;
  transition: 0.5s;
  color: transparent;
}

.Q-box .A.active {
  color: #000;
}

.Q-box .Q .icon {
  width: 15px;
  line-height: 15px;
  height: 15px;
  overflow: hidden;
  color: #ccc;
  transition: color 0.5s;
  position: relative;
}

.Q-box .Q:hover .icon {
  color: #000;
}

.Q-box .Q.active .icon {
  color: #000;
}

.Q-box .Q .icon .positive,
.Q-box .Q .icon .negative {
  position: absolute;
  top: 50%;
  left: 50%;
  overflow: hidden;
  opacity: 0;
  transition: transform 0.5s, opacity 0.5s;
}

.Q-box .Q .icon .positive.active,
.Q-box .Q .icon .negative.active {
  opacity: 1;
}

.Q-box .Q .icon .positive {
  transform: translateX(-50%) translateY(-50%) rotate(90deg);
}

.Q-box .Q .icon .negative {
  transform: translateX(-50%) translateY(-50%) rotate(-90deg);
}

.Q-box .Q .icon .positive.active {
  transform: translateX(-50%) translateY(-50%) rotate(0deg);
}

.Q-box .Q .icon .negative.active {
  transform: translateX(-50%) translateY(-50%) rotate(0deg);
}

JavaScript

function collapse() {
  let activeQ = event.target;
  let Qbox = activeQ.closest("div.Q-box");
  let positive = Qbox.querySelector(".positive");
  let negative = Qbox.querySelector(".negative");
  let A = Qbox.querySelector("p.A");

  activeQ.classList.toggle("active");
  positive.classList.toggle("active");
  negative.classList.toggle("active");

  A.classList.toggle("active");
  if (A.style.height) {
    A.style.height = null;
  } else {
    A.style.height = A.scrollHeight + "px";
  }
}