具代表性的面試主題

前端面試題:如何用 CSS @function 重用設計 Token?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

請實作一個把間距 Token 轉換為響應式長度的 CSS @function,並說明它與自訂屬性、Sass 函式及瀏覽器降級的邊界。

1. 題目與適用場景

設計系統有一組間距 Token,元件需要依密度和容器寬度計算 padding。團隊想減少重複的 calc(),同時保留純 CSS、主題覆寫和舊瀏覽器可用性。請使用 CSS @function 設計方案,並說明未支援瀏覽器如何取得安全回退。

2. 面試官考察點

  • 是否理解 @function 定義的是 CSS 自訂函式,呼叫名稱必須是帶 -- 的 dashed-ident。
  • 是否能正確宣告參數、預設值、可選型別和 result,並理解函式主體不會像 JavaScript 一樣遇到宣告就立即回傳。
  • 是否能區分自訂函式、自訂屬性、Sass 編譯期函式與執行期級聯。
  • 是否能處理特性偵測、主題繼承、循環依賴、瀏覽器相容與可存取的漸進增強。

3. 回答前需要釐清的問題

  1. 目標瀏覽器範圍是否包含尚未實作 CSS Functions 的版本?
  2. Token 是固定長度、百分比,還是允許 calc() 與容器單位?
  3. 函式參數錯誤時應採用預設值、整條宣告失效,還是由元件提供回退?
  4. 主題 Token 來自 :root、元件作用域還是 Shadow DOM?

4. 30 秒回答框架

我會把函式定義與回退宣告放在同一規則中:先寫可工作的靜態 padding,再用 @supports (top: --probe()) 覆寫為自訂函式結果。函式使用型別限制和預設參數,最後透過 result 產生長度。自訂屬性負責主題輸入,函式負責計算;舊瀏覽器忽略未知函式並保留前面的回退宣告。

5. 分步驟深入解答

第一步:定義參數與回傳值

css
@function --space(--step <integer>: 2, --base <length>: 4px) {
  result: calc(var(--base) * var(--step));
}

參數是區域自訂屬性,可宣告 CSS 型別和預設值。result 提供函式最終值;它不是 JavaScript 的提前 return,函式宣告規則仍會繼續依 CSS 語意處理。

第二步:把函式接到設計 Token

css
:root {
  --space-base: 4px;
}

.card {
  padding: 16px;
  padding: --space(3, var(--space-base));
}

第一條 padding 是舊瀏覽器回退,第二條只在能解析自訂函式時生效。Token 仍透過自訂屬性級聯,元件可在主題或區域作用域覆寫 --space-base

第三步:處理型別與無效值

型別限制用於提早拒絕不符合語法的資料;預設值只覆蓋參數缺省,不會把任意字串變成合法長度。應為負值、單位錯誤和缺少 Token 定義設計測試,並避免把使用者可控字串直接拼進 CSS 函式參數。

第四步:理解作用域與依賴

函式參數在函式主體內表現為區域自訂屬性,呼叫點仍受級聯、繼承與層疊順序影響。函式依賴的 Token 不應反向依賴函式結果,否則可能形成循環自訂屬性,整條宣告會變為無效。

第五步:特性偵測與漸進增強

css
.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 檢查無效計算值。

公開來源

同類題目