1421 字
7 分鐘

CSS interpolate-size 怎麼用?讓 height: auto 動畫保留 fallback

CSS 做展開面板時,最常遇到的限制是:關閉狀態可以寫成 height: 0,開啟狀態卻需要內容決定高度,也就是 height: auto。傳統 transition 不能直接在數字和 intrinsic size 之間補間,所以面板常常只能瞬間跳開,或改用估算過的 max-height。

interpolate-size: allow-keywords 提供另一條漸進增強路徑,讓瀏覽器在長度和 auto、min-content、max-content、fit-content 等 intrinsic size 之間做過渡。不過 MDN 目前仍將它標為非 Baseline,不能假設所有瀏覽器都支援。

先看沒有這個屬性的限制#

假設按鈕會替面板切換 is-open class:

.panel {
height: 0;
overflow: hidden;
transition: height 240ms ease;
}
.panel.is-open {
height: auto;
}

在不支援 intrinsic size interpolation 的瀏覽器中,0 到 auto 沒有可計算的中間數值,因此不會得到預期的連續動畫。把 max-height 設得很大雖然看似能繞過問題,卻會帶來兩個實際麻煩:

  • 面板內容較短時,動畫時間和真實高度不一致。
  • 內容高度有上限時,使用者可能看不到超過上限的內容。

用 interpolate-size 讓 height: auto 可過渡#

把屬性放在 ,讓後代元素繼承:

:root {
interpolate-size: allow-keywords;
}
.panel {
height: 0;
overflow: hidden;
transition: height 240ms ease;
}
.panel.is-open {
height: auto;
}

這個寫法的重點不是「所有高度都能動畫」,而是明確允許一端是長度、另一端是 intrinsic size。interpolate-size 預設仍是 numeric-only;沒有 allow-keywords 時,瀏覽器不會把 auto 當成可補間的目標。

如果只想讓某個元件使用,也可以把屬性縮小到元件容器:

.accordion {
interpolate-size: allow-keywords;
}

局部套用比較容易控制影響範圍,尤其頁面同時有很多會改變尺寸的互動元件時。

需要計算時才用 calc-size()#

calc-size() 適合在 intrinsic size 上再做計算,例如開啟面板時需要多留一段空間:

.panel.is-open {
height: calc-size(auto, size + 1rem);
}

把 calc-size() 放進值裡,等同於對該選擇啟用 interpolate-size: allow-keywords。如果沒有要做計算,直接使用 interpolate-size 會比較容易讀懂,也能把「允許 intrinsic size 動畫」和「對尺寸做運算」分開。

還要注意:interpolate-size 不能讓兩個 intrinsic size 彼此互相補間;至少有一端要是 length-percentage。因此 height: max-content 到 height: auto 不能只靠這個屬性保證動畫。

用 @supports 保留無動畫 fallback#

這個功能仍不是所有瀏覽器都支援,應把「內容可用」放在「動畫存在」之前:

.panel {
height: 0;
overflow: hidden;
}
.panel.is-open {
height: auto;
}
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
.panel {
transition: height 240ms ease;
}
}
@media (prefers-reduced-motion: reduce) {
.panel {
transition: none;
}
}

不支援的瀏覽器會直接從 0 切到 auto,但不會因為等不到動畫而把內容留在關閉狀態。若產品需要更細緻的跨瀏覽器動態高度,可改用 JavaScript 量測實際高度;那是另一種成本與維護邊界,不要把 max-height 的估值誤當成通用解法。

動畫之外,還要處理可存取性#

CSS 高度切換只處理視覺狀態,按鈕與面板之間的狀態仍要由 HTML 或 JavaScript 維護。至少確認:

  • 切換按鈕的 aria-expanded 會隨開關更新。
  • aria-controls 指向正確的面板 id。
  • 面板關閉時,不會讓鍵盤焦點落在視覺上不可見的控制項。
  • 使用 prefers-reduced-motion 時不要求使用者等待動畫。
  • 若使用 hidden 屬性,先確認你的切換流程不會因為元素立刻消失而失去動畫目標。

可以先用瀏覽器的 CSS 支援檢查確認語法是否可用:

CSS.supports("interpolate-size", "allow-keywords");
CSS.supports("height", "calc-size(auto, size + 1rem)");

這個檢查只代表目前瀏覽器理解語法,不代表你的面板內容、overflow、focus 管理或 reduced motion 行為都已驗證。仍要以實際開啟、關閉、鍵盤操作和窄螢幕測試為準。

什麼時候不要用它#

以下情境不適合直接套用:

  1. 元件的開關狀態由 display: none 控制,元素沒有可用的尺寸過渡階段。
  2. 內容高度頻繁變動,動畫期間可能持續重新排版,應先處理資料載入與 layout stability。
  3. 目標瀏覽器不支援,而且產品不接受無動畫 fallback。
  4. 需求其實是固定高度或裁切效果,使用明確的長度值會更容易驗證。

interpolate-size 適合拿來改善「內容決定尺寸」的互動,不是所有展開元件的效能開關。若元件本身還有大量畫面外內容,應另外評估 content-visibility 與預估尺寸造成的版面位移

結論:先做可用 fallback,再加 intrinsic size 動畫#

interpolate-size: allow-keywords 可以讓 height: 0 與 height: auto 之間有更自然的過渡,但目前仍要把它當成 progressive enhancement。先確保面板在不支援時仍能開啟、關閉和使用鍵盤,再透過 @supports 加上動畫;只有需要運算時才引入 calc-size()。

常見問題#

Q: interpolate-size 能讓兩個 auto 或兩個 intrinsic size 互相動畫嗎?#

A: 不能只靠這個屬性保證。官方定義是讓長度或百分比和 intrinsic size 之間補間,兩端都是 intrinsic size 時仍沒有可用的數值插值路徑。

Q: calc-size() 和 interpolate-size 要選哪一個?#

A: 只要允許 auto 等 intrinsic size 參與動畫,使用 interpolate-size 比較直接;需要在 intrinsic size 上加減長度或做其他計算時,才使用 calc-size()。

Q: 這個 CSS 功能可以直接用在 production 嗎?#

A: 先查目標瀏覽器的相容性,再用 @supports 提供無動畫 fallback。MDN 目前將 interpolate-size 標為非 Baseline,因此不能把支援狀態當成全瀏覽器一致。

參考資料:

MDN:interpolate-size

MDN:calc-size()

Chrome for Developers:Animate to height: auto

CSS interpolate-size 怎麼用?讓 height: auto 動畫保留 fallback
https://laplusda.com/posts/css-interpolate-size-auto-transition/
作者
Zero
發佈於
2026-08-07
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。