前言
手風琴是一種常見的網頁 UI 模式,通常是一系列垂直堆疊的標題可以用於展開收合顯示不同資訊,也有額外的稱呼像是:
- Collapsible
- Details
- Expandable
而在 HTML 當中有項新穎的語法 <details>
和 <summary>
可以幫助我們快速實現類似的功能,並且配合上新的 CSS interpolate-size
和 transition-behavior
製作滑順的展開閉合動畫。
基礎手風琴
HTML 添加了 <details>
讓我們可以用原生的方式表達可被開合的區塊,其中 <summary>
代表區塊的標題,範例如下:
<details> <summary>Section Summary Title Here</summary> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ad consectetur nisi repellendus atque. Praesentium mollitia sapiente libero aspernatur. Hic ipsa id eveniet sapiente totam soluta exercitationem iusto, quaerat delectus ratione.</details>
Section Summary Title Here
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ad consectetur nisi repellendus atque. Praesentium mollitia sapiente
libero aspernatur. Hic ipsa id eveniet sapiente totam soluta exercitationem iusto, quaerat delectus ratione.
群組手風琴
要綁定多個手風琴開合狀態的話可以使用相同的 name
屬性,這樣就能強制只能打開單個相同 name
屬性的手風琴:
<details name="exclusive"> <summary>Section 1</summary> <p>Content for section 1.</p></details><details name="exclusive"> <summary>Section 2</summary> <p>Content for section 2.</p></details>
Section 1
Content for section 1.
Section 2
Content for section 2.
預設開啟手風琴
要預設特定手風琴項目開啟的話可以使用 open
屬性:
<details open> <summary>Section 1</summary> <p>Content for section 1.</p></details>
Section 1
Content for section 1.
添加動畫
要選擇 details 的內容可以使用 ::details-content 偽元素,在開啟的狀態設置不同的高度與 transition
就可以根據開合狀態進行動畫。
details::details-content { background-color: red; height: 0; transition: height 1s;}
details[open]::details-content { height: auto;}
使高度能被動畫: interpolate-size: allow-keyword
會發現就算添加 transition
指示元素伸展收合時 height
也不會有任何的動畫,在早期這個問題算是無解了,只能用 JS 去計算高度並更改屬性來達成動畫效果。幸好如今有全新的實驗性 CSS 語法:interpolate-size: allow-keywords
(尺寸插值變化允許關鍵字) 協助我們替 auto
、fit-content
、max-content
這類屬性計算 animation
與 transition
。它是一種可以被子元素繼承的樣式設置,所以就算設定在文件根部或個別使用的元素上都可行:
:root { interpolate-size: allow-keywords;}
使顯示可被動畫: content-visibility
會發現在收闔時不會有任何動畫而是直接消失,這是因為手風琴關閉時內容顯示會被設置為無,針對這點我們也會需要設置相關的動畫,並且它是種 discrete 動畫!意味著它不會存在中間狀態或數值,會需要 transition-behavior: allow-discrete
才能讓其他動畫完成後才進行切換:
transition: height 1s, content-visibility 1s;transition-behavior: allow-discrete;
總結
如果依照前面的步驟操作下來,你會得到一個最小可運作的原生手風琴,並且有不錯的開闔動畫!此外可以參考看看 Kevin Powell 更精緻的實踐以及他的介紹影片:Animate details & summary with a few lines of CSS - Kevin Powell
See the Pen details & summary by Riceball (
@riecball) on CodePen.
延伸閱讀
- Accordion - the component gallery
- Native HTML: Accordion Revisited - Andrew Bone
- This new CSS property just solved animating to height auto - Kevin Powell
- 这啥?CSS calc-size 和 interpolate-size,真学不动了 - 鑫空间-鑫生活
- interpolate-size - MDN