1. 題目與適用場景
設計系統有一組間距 Token,元件需要依密度和容器寬度計算 padding。團隊想減少重複的 calc(),同時保留純 CSS、主題覆寫和舊瀏覽器可用性。請使用 CSS @function 設計方案,並說明未支援瀏覽器如何取得安全回退。
2. 面試官考察點
- 是否理解
@function定義的是 CSS 自訂函式,呼叫名稱必須是帶--的 dashed-ident。 - 是否能正確宣告參數、預設值、可選型別和
result,並理解函式主體不會像 JavaScript 一樣遇到宣告就立即回傳。 - 是否能區分自訂函式、自訂屬性、Sass 編譯期函式與執行期級聯。
- 是否能處理特性偵測、主題繼承、循環依賴、瀏覽器相容與可存取的漸進增強。
3. 回答前需要釐清的問題
- 目標瀏覽器範圍是否包含尚未實作 CSS Functions 的版本?
- Token 是固定長度、百分比,還是允許
calc()與容器單位? - 函式參數錯誤時應採用預設值、整條宣告失效,還是由元件提供回退?
- 主題 Token 來自
:root、元件作用域還是 Shadow DOM?
4. 30 秒回答框架
我會把函式定義與回退宣告放在同一規則中:先寫可工作的靜態 padding,再用 @supports (top: --probe()) 覆寫為自訂函式結果。函式使用型別限制和預設參數,最後透過 result 產生長度。自訂屬性負責主題輸入,函式負責計算;舊瀏覽器忽略未知函式並保留前面的回退宣告。
5. 分步驟深入解答
第一步:定義參數與回傳值
@function --space(--step <integer>: 2, --base <length>: 4px) {
result: calc(var(--base) * var(--step));
}參數是區域自訂屬性,可宣告 CSS 型別和預設值。result 提供函式最終值;它不是 JavaScript 的提前 return,函式宣告規則仍會繼續依 CSS 語意處理。
第二步:把函式接到設計 Token
:root {
--space-base: 4px;
}
.card {
padding: 16px;
padding: --space(3, var(--space-base));
}第一條 padding 是舊瀏覽器回退,第二條只在能解析自訂函式時生效。Token 仍透過自訂屬性級聯,元件可在主題或區域作用域覆寫 --space-base。
第三步:處理型別與無效值
型別限制用於提早拒絕不符合語法的資料;預設值只覆蓋參數缺省,不會把任意字串變成合法長度。應為負值、單位錯誤和缺少 Token 定義設計測試,並避免把使用者可控字串直接拼進 CSS 函式參數。
第四步:理解作用域與依賴
函式參數在函式主體內表現為區域自訂屬性,呼叫點仍受級聯、繼承與層疊順序影響。函式依賴的 Token 不應反向依賴函式結果,否則可能形成循環自訂屬性,整條宣告會變為無效。
第五步:特性偵測與漸進增強
.card {
padding: 16px;
}
@supports (padding: --space(3, 4px)) {
.card {
padding: --space(3, var(--space-base, 4px));
}
}@supports 只判斷解析能力,不能證明所有函式分支都符合業務限制。仍應保留穩定回退、檢查計算後的版面,並在不支援時確保文字、焦點與觸控目標不被壓縮。
6. 高品質示範回答
我會先提供靜態padding,再在@supports中使用@function計算 Token。自訂屬性負責主題級聯,函式參數宣告長度或整數型別並透過result回傳值。錯誤輸入不能依賴字串拼接;我會覆蓋缺省參數、單位錯誤、負值和循環依賴。由於 CSS Functions 仍有相容差異,回退宣告必須完整可用,並透過實際瀏覽器驗證計算樣式和可存取尺寸。
7. 常見錯誤
- 把 CSS
@function當成 Sass 編譯期函式 → 發布後才發現瀏覽器不解析 → 保留執行期回退並做@supports偵測。 - 在參數傳入無單位數字卻宣告
<length>→ 整條宣告失效 → 明確型別和預設單位。 - 認為函式會修改自訂屬性 → 主題覆寫不生效 → 把 Token 輸入與
result輸出分開。 - 只寫
@supports沒有基礎宣告 → 不支援瀏覽器出現預設間距 → 先寫可用回退。 - 用函式互相引用 → 循環依賴使計算值無效 → 保持 Token 依賴方向單向。
8. 追問及應對
追問一:它和自訂屬性有什麼區別?
自訂屬性保存可級聯的值;自訂函式接收參數並計算結果。函式可以重用計算邏輯,但輸入仍可來自繼承的自訂屬性。
追問二:它和 Sass 函式有什麼區別?
Sass 函式在建置時產生 CSS,無法讀取執行期主題或容器狀態;CSS 自訂函式在瀏覽器級聯和計算階段執行,能回應執行期 Token,但需要處理相容性。
追問三:如何偵測函式是否可用?
用 @supports (padding: --space(1, 4px)) 偵測語法解析能力,同時保留前置回退。測試不能只看規則是否被接受,還要讀取實際計算值。
追問四:如何避免循環依賴?
讓基礎 Token 只依賴原始值,函式只讀取 Token 並輸出派生值;禁止 Token 再引用包含該函式結果的屬性,並在 DevTools 檢查無效計算值。