CSS高度動畫新招

如果你問我,HTML、JavaScript 跟 CSS 哪個最難,我大概會回答 CSS,並且送你一張 CSS 拉窗簾.gif。跟 JavaScript 比起來,CSS 進化的速度來得更快,每隔幾個月就出來一個新東西,解決了許多的經典難題。

不過就算沒有這些新東西,其實也能做出一個堪用的版本,或是乾脆直接用 JavaScript 來弄,大部分也都能搞定。但正是因為如此,導致許多人(包括我)的 CSS 知識可能一直都沒有進化,原地踏步,不知道有哪些新的東西。

舉個例子,一個點擊可以展開,再點一次可以收起來的摺疊元件(Collapse)大家應該都不陌生。那如果折疊的時候想加上一點動畫該怎麼弄?沒弄過的人會說這簡單,不就加個 transition: height 0.3s; 就行了嗎?

弄過的人會跟你說這樣沒用,因為 height 是 auto,這種狀況下不會有 transition。要解決的話不外乎就是三招,第一招是寫死固定高度,但通常沒辦法滿足需求;第二招是改成用固定的 max-height,既能動又不會真的讓高度寫死,而缺點是動畫時間會很奇怪;第三招則是請 JavaScript 出馬,在折疊前先把高度取出來再設置上去。

除了廣為人知的這三招以外,最近看到另外兩招新的也可以解決,第一個是 ChatGPT 推薦我用的 grid + grid-template-rows,利用 grid 會自己調整大小但又不是 auto 的特性來做,就能有 transition。

第二個其實才是今天想講的主題,只要在展開時把高度改成 height: calc-size(auto, size); 就搞定了,酷吧。

不過瀏覽器支援度很差,去年九月推出的 Chrome & Edge 129 才開始支援,其他瀏覽器直接死給你看。或許這也是為什麼許多新的 CSS 方法沒有受到這麼多關注吧?就算知道了,可能要先等個半年一年才能等到所有主流瀏覽器的支援,就算到了那時,整體支援率可能還只有 50% 不到,還要再等個三五年才能實際用在 production 上。

但總之呢,能用純 CSS 解決這個千古難題還是挺讚的對吧。

下次碰到需要幫 height: auto 加上 transition 時,如果可以保證使用者的瀏覽器都很新,不妨試試看。

評論