calc-size() 是 CSS 函式,用於對 auto、min-content 和 fit-content 等內建大小關鍵字執行數學運算。必要:只有在需要透過計算或限制修改內建大小時,才使用 calc-size();如果是簡單的關鍵字動畫 (例如 0 到 auto),則必須使用 interpolate-size: allow-keywords。
導入步驟
- 找出內建基準:判斷應以哪個內建關鍵字 (
auto、min-content等) 做為計算基準。 - 定義限制:在第二個引數中使用
clamp()、min()或max()等 CSS 數學函式,對內建大小強制執行設計限制。 - 強制:提供備用方案:請務必在使用
calc-size()的屬性之前,立即宣告標準大小關鍵字或長度,確保版面配置在不支援的瀏覽器中仍能正常運作。 - 套用邏輯屬性:預設使用
inline-size或block-size等邏輯屬性,確保計算結果符合文件的書寫模式。 - 選用:漸進增強:將複雜的版面配置邏輯或動畫包裝在
@supports (inline-size: calc-size(auto, size + 0px))區塊中,只向支援的瀏覽器提供進階功能。
基本語法
/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
/* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
inline-size: min-content;
/* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
inline-size: calc-size(min-content, size + 2rem);
}
有效的基準引數 (<calc-size-basis>)
第一個引數定義計算的「基本」大小。
標準關鍵字:
auto:元素的預設大小。min-content:元素在不溢出的情況下可採用的最小尺寸。max-content:元素容納一行所有內容所需的大小。fit-content:等同於clamp(min-content, auto, max-content)。content:只有在flex-basis屬性中使用calc-size()時才有效。
特殊引數:
any:在特定內建類型不明或巢狀計算時,使用的一般基礎。- 巢狀
calc-size():允許進行多步驟或條件式計算。 <calc-sum>:特定長度、百分比或數學運算式 (例如100px或20%)。以固定值做為基準時,您仍可使用size關鍵字 (但僅限於第二個引數),代表該基準的解析值。
強制:size 關鍵字在第一個引數 (<calc-size-basis>) 中無效。這是一個區域變數,僅用於從第二個引數 (<calc-sum>) 內參照回基礎。
有效的計算引數 (<calc-sum>)
第二個引數是數學運算式。
- 通常會使用
size關鍵字來參照基準值。 - 雖然
size關鍵字並非必要,但如果省略,計算結果會解析為固定值,完全忽略基準。 - 可包含標準數學運算子 (
+、-、*、/)。 - 可包含
clamp()、min()、max()和round()等 CSS 數學函式。 - 必要:
calc-size()每次計算只能使用「一個」內建大小值 (基準)。您無法在同一個calc-size()呼叫中混合使用內建大小關鍵字。
應用實例
在原始大小之間加上動畫效果
根據預設,瀏覽器無法在長度 (例如 0px) 和內建關鍵字 (例如 auto) 之間插補。將關鍵字包裝在 calc-size() 中,即可將其設為可插補的值。
選擇合適的動畫工具
強制:使用
interpolate-size: allow-keywords:用於在不進行任何數學修改的情況下,對內建大小 (例如height: 0到height: auto) 進行簡單的動畫。這是簡單關鍵字內插的必要方法,理想情況下應透過:root全域套用。:root { /* Best practice: Enable keyword interpolation globally */ interpolate-size: allow-keywords; } .item { height: 0; transition: height 0.3s ease; } .item.open { /* Simple interpolation from 0 to auto now works without calc-size() */ height: auto; }使用
calc-size():僅限需要在轉換期間對內建大小執行數學運算 (例如新增邊框間距或限制大小) 時。
.accordion-content {
display: block;
overflow: hidden;
/* MANDATORY: Fallback value for closed state */
block-size: 0;
transition: block-size 0.3s ease-out;
}
.accordion-content.open {
/* MANDATORY: Fallback value for open state */
block-size: auto;
/*
DO: Use calc-size(auto, ...) to enable animation from 0 to the element's
intrinsic size while doing a calculation (in this case, adding a space of 2rem).
*/
block-size: calc-size(auto, size + 2rem);
}
MANDATORY: Interpolation between two intrinsic sizing keywords is not possible directly. 轉場效果的一端必須是長度或百分比。
尊重使用者動作偏好設定
如果動畫會改變大型版面配置區域的大小,可能會對前庭障礙使用者造成特別嚴重的干擾。必要:請務必使用 prefers-reduced-motion 媒體查詢,簡化或盡量減少非必要的動畫,尊重使用者的動作偏好設定。常見策略包括完全停用動作、縮短持續時間,或將版面配置位移替換為細微的不透明度轉場效果。
.accordion-content {
opacity: 0;
transition: block-size 0.3s ease, opacity 0.3s ease;
}
.accordion-content.open {
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.accordion-content {
/*
EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
Setting the block-size instantly and transitioning opacity
provides a clear state change without large-scale motion.
*/
transition: opacity 1.5s ease;
}
.accordion-content.open {
/* Jump the size instantly */
block-size: auto;
}
}
對內建大小套用限制
您可以將 calc-size() 與任何 CSS 數學函式 (例如 min()、max()、clamp() 或 round()) 搭配使用,確保元素的固有大小不超出設計邊界。
.dynamic-container {
/* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
inline-size: fit-content;
/*
DO: Establish a dynamic size based on content, while:
1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
2. Modifying the intrinsic size with fixed or relative offsets
*/
inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}
重要考量
- 百分比陷阱:
<calc-sum>內的百分比是根據容器大小解析,而非size關鍵字。舉例來說,calc-size(auto, size + 10%)會將父項寬度的 10% 加到元素的auto寬度,這可能會導致非預期的結果或溢位。 - 計算規定:強制:請使用
interpolate-size: allow-keywords,而非calc-size()處理簡單動畫 (例如0至auto)。只有在版面配置需要對內建基準進行動態數學調整時,才應使用calc-size()。 - 效能注意事項:為
inline-size或block-size等盒模型屬性加上動畫效果,會觸發版面配置重新計算,這可能會耗費大量資源。calc-size()動畫主要用於版面配置關鍵元素,且非版面配置替代方案不足的情況。
備用策略
calc-size() 和 interpolate-size 是漸進增強。在不支援這些屬性的瀏覽器中,系統會忽略這些屬性,版面配置仍可正常運作,但內建關鍵字的動畫會跳轉,而非轉場。請務必提供標準關鍵字或長度做為備用。
.element {
/* Fallback for browsers that don't support calc-size() */
inline-size: fit-content;
/* Modern browsers will override the fallback */
inline-size: calc-size(fit-content, size + 2rem);
}
動畫和轉場效果備用方案
在不支援 calc-size() 或 interpolate-size 的瀏覽器中,涉及內建大小關鍵字的轉場效果將無法插補。
- 優雅降級:預設備用方案是狀態之間的「即時跳轉」(例如從
0到auto)。這通常可以接受,因為版面配置仍可正常運作。 - 強化體驗:使用
@supports套用複雜的版面配置邏輯或額外樣式,只有在能流暢呈現內建動畫時,這類效果才有意義。 - 避免使用 JS 測量:雖然您可以使用 JavaScript 測量元素,並手動為其尺寸加上動畫效果,但這通常不必要,且可能導致版面配置抖動。建議現代網頁應用程式採用原生「即時跳轉」做為備用方案。
如果是動畫,備用體驗會立即跳至最終大小。如要偵測 CSS 或 JavaScript 的支援情形,請按照下列步驟操作:
/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
.element {
/* Apply advanced logic only when supported */
}
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
// Apply advanced sizing or animations
}