CSS Accordion 手風琴摺疊選單

手風琴(Accordion)是一種常見的 UI 元件,允許使用者透過點擊標題來展開或收合內容。這種佈局非常適合用於 FAQ 常見問題頁面、側邊導航欄或任何需要節省空間的場景。

在本教學中,我們將介紹如何使用純 CSS 實現手風琴效果,而不需要編寫任何 JavaScript。

使用 details 和 summary(推薦)

HTML5 原生提供了 <details><summary> 標籤,這是最簡單且語義化最好的方式來實現摺疊效果。

<details class="accordion">
  <summary>什麼是 CSS 手風琴?</summary>
  <div class="content">
    <p>手風琴是一種垂直堆疊的內容列表,使用者可以點擊標題來切換顯示內容。</p>
  </div>
</details>

樣式美化

雖然原生的標籤已經有功能,但我們通常會加上一些樣式讓它更美觀:

.accordion {
  border: 1px solid #ddd;
  border-radius: 8px;
  margin-bottom: 10px;
  overflow: hidden;
}

.accordion summary {
  padding: 16px;
  background-color: #f8f9fa;
  cursor: pointer;
  font-weight: bold;
  list-style: none; /* 隱藏原生箭頭 */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* 自定義箭頭 */
.accordion summary::after {
  content: '▶';
  transition: transform 0.3s;
}

/* 當標籤展開時旋轉箭頭 */
.accordion[open] summary::after {
  transform: rotate(90deg);
}

.accordion .content {
  padding: 16px;
  border-top: 1px solid #ddd;
}

實作預覽 (Details/Summary)

什麼是 CSS 手風琴?

手風琴是一種垂直堆疊的內容列表,使用者可以點擊標題來切換顯示內容。

使用 Checkbox 技巧

如果你需要更複雜的動畫效果或特定的佈局控制(有些舊版瀏覽器對 details 動畫支援較差),可以使用 checkbox 配合 label 的技巧。

HTML 結構

<div class="accordion-item">
  <input type="checkbox" id="item1" class="accordion-input">
  <label for="item1" class="accordion-label">點我展開更多資訊</label>
  <div class="accordion-content">
    <p>這是一個使用 Checkbox 技巧實作的手風琴。不需要 JavaScript 也能做到!</p>
  </div>
</div>

CSS 實作

.accordion-item {
  width: 100%;
}

.accordion-input {
  display: none; /* 隱藏實際的 checkbox */
}

.accordion-label {
  display: block;
  padding: 15px;
  background: #007bff;
  color: white;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
  background: #f4f4f4;
}

/* 當 Checkbox 被選中時,展開相鄰的內容 */
.accordion-input:checked ~ .accordion-content {
  max-height: 200px; /* 設定一個足夠大的高度 */
  padding: 15px;
}

實作預覽 (Checkbox Hack)

這是一個使用 Checkbox 技巧實作的手風琴。不需要 JavaScript 也能做到!

常見實作技巧

一次只能展開一個 (Radio Button)

如果你希望使用者點擊一個項目時,其他項目自動收合,只需將上述技巧中的 type="checkbox" 改為 type="radio",並給予相同的 name 屬性即可。

<input type="radio" name="my-accordion" id="r1">
<label for="r1">項目一</label>
<div class="content">...</div>

<input type="radio" name="my-accordion" id="r2">
<label for="r2">項目二</label>
<div class="content">...</div>

加入平滑動畫

在使用 max-height 製作動畫時,請注意不要設定過大的值(例如 9999px),否則動畫速度會顯得太快或延遲,因為瀏覽器會根據設定的數值來計算時間。建議設定一個稍微大於內容實際高度的值即可。

雖然純 CSS 手風琴很方便,但在處理動態內容高度或複雜的可訪問性需求(Accessibility)時,配合少量的 JavaScript 往往能提供更好的使用者體驗。