題幹與適用場景
元件庫使用 --accent、--progress 與 --card-size 等自訂屬性。設計要求它們平滑過渡,但目前變數是無型別字串,錯誤值會靜默傳播,子元件還會意外繼承主題值。請說明何時用 CSS @property 註冊這些變數,以及如何處理預設值、無效值、繼承與瀏覽器相容。
這道題適合前端、設計系統與 Web 效能職位。重點是理解 CSS Properties and Values API 的約束邊界,而不是把所有變數都註冊一次。回答應涵蓋語法、初始值、繼承、動畫插值、作用域、漸進增強與測試。
面試官考察點
強回答會指出普通自訂屬性按字串計算,預設繼承;註冊屬性可以宣告型別、初始值與繼承行為,瀏覽器在計算階段校驗無效值。它會說明 syntax 與 inherits 是必需描述子,非通配語法通常需要計算獨立的 initial-value,並判斷動畫、型別約束和非繼承元件變數的實際收益。還要避免把 @property 當成 JavaScript 狀態或效能保證。
回答前需要釐清的問題
- 變數承載什麼型別:顏色、長度、角度、數字,還是任意 token 字串?
- 它是否需要平滑動畫,還是只在主題切換時離散替換?
- 值是否應繼承到子元件,元件邊界是否需要隔離?
- 無效值出現時應回退到初始值、祖先值,還是讓宣告失效?
- 目標瀏覽器、伺服器端渲染、舊版降級與設計 token 發布流程是什麼?
30 秒回答框架
「普通自訂屬性是可繼承的字串,適合開放式 token;需要型別校驗、非繼承預設值或平滑動畫時,我會用 @property 註冊。註冊時明確 syntax、inherits 與計算獨立的 initial-value,讓無效賦值回到可預測的初始值。對舊瀏覽器保留普通變數作為降級,並用元件級測試驗證繼承、無效值、動畫與主題切換,而不是假設註冊本身一定更快。」
分步驟深入解答
第一步:區分普通變數與註冊屬性
普通 --name 變數參與級聯並預設繼承,瀏覽器把值當作 token 序列處理。它適合顏色 token、間距字串或需要自由組合的值,但瀏覽器不知道你期望的是顏色還是長度。@property 為同一變數增加型別、繼承與預設值中繼資料。
第二步:選擇明確的 syntax
只為需要約束或插值的變數註冊型別。例如顏色、數字與角度分別使用對應的 CSS 型別語法。避免為了「更嚴格」把需要多個 token 的複合變數誤宣告成單一型別,導致合法主題值被丟棄。
第三步:設定 inherits 與 initial-value
inherits 必須明確。主題色通常需要繼承,元件內部的局部尺寸或動畫進度可能應設為不繼承。非通配語法需要計算獨立的 initial-value,例如長度使用固定單位而不是依賴父級的百分比。缺少必需描述子會讓整條註冊規則無效。
第四步:理解無效值與回退
註冊屬性在計算時校驗值。與型別不符的賦值不會生效,屬性會回到註冊的初始值、繼承值或級聯中的其他有效結果,具體取決於 inherits 與宣告位置。全域關鍵字 initial、inherit、unset 與 revert 仍有特殊語義,不能當成普通字串測試。
第五步:利用可插值動畫
未註冊的自訂屬性通常只能離散變化,瀏覽器無法對任意字串計算中間值。註冊為顏色、長度或數字後,瀏覽器知道如何插值,可以驅動漸變、進度與旋轉動畫。仍需測試動畫時長、合成層、減少動效偏好與大量元素更新的實際成本。
第六步:控制元件邊界
把全域主題 token 與元件內部狀態分開命名。可繼承值適合主題向下傳遞;不繼承的屬性讓元件使用自己的初始值,避免父級同名變數污染內部動畫。若變數需要跨 shadow DOM 或容器共享,先明確命名空間與暴露 API,再決定是否註冊。
第七步:提供漸進增強
先提供普通自訂屬性與靜態終態,讓不支援 @property 的瀏覽器仍能渲染可用 UI;支援註冊的環境再獲得型別約束與插值動畫。不要在關鍵版面只依賴註冊屬性,必要時用 @supports (property: --x) 或能力偵測選擇增強路徑。
第八步:驗證錯誤與瀏覽器行為
測試合法值、錯誤型別、缺失初始值、繼承開關、主題覆蓋、動畫中途改值與 SSR 首屏。檢查舊瀏覽器、開發者工具計算值和視覺回歸。MDN 提醒註冊屬性在計算階段校驗,錯誤宣告可能整條被忽略,因此建置檢查與執行時樣例都要涵蓋。
設計取捨與邊界
註冊屬性會增加宣告和設計 token 的維護成本,也可能讓不熟悉 CSS API 的貢獻者以為所有值都能自由替換。我會優先註冊有明確型別、需要動畫或必須阻止繼承污染的變數;開放式內容 token 繼續使用普通自訂屬性。
不要把型別校驗當作安全邊界或跨瀏覽器一致性的保證。瀏覽器支援、解析時機和動畫合成仍要以目標矩陣實測;關鍵無障礙狀態應有靜態樣式與減少動效路徑。
落地計畫與證據
先挑選一個進度或顏色元件做試點,記錄變數用途、型別、繼承策略與回退值。用一組合法與非法樣例驗證計算結果,再比較註冊前後的動畫流暢度、樣式重算與舊瀏覽器表現。試點通過後,把註冊宣告、token 文件與視覺回歸加入元件庫發布檢查。
每次修改 syntax 或 inherits 都視為行為變更,檢查子元件覆蓋、主題切換和持久化快照。若使用者報告顏色跳變或尺寸回退,先查看計算值與支援路徑,不要只調大動畫時長。
常見誤區與追問
把所有 CSS 變數都註冊
任意 token、複合值與實驗性字串不一定有穩定語法。只註冊需要型別、預設值、繼承控制或插值的變數。
忘記 initial-value 的計算獨立性
非通配語法的初始值不能依賴上下文計算。使用百分比或 em 可能讓註冊規則無效,應改用計算獨立的單位或通配語法並承擔較弱約束。
以為 invalid 值會回退到上一個合法宣告
註冊屬性在計算階段校驗,錯誤賦值可能回到初始值或繼承結果,而不是保留相鄰的舊值。測試計算後的樣式,不能只看原始碼順序。
把 inherits 當成 cascade 隔離
inherits: false 只控制預設繼承;作者仍可明確寫 inherit,元件也可能透過其他 token 接收父級值。邊界需要命名、文件與測試共同保證。
如何相容不支援 @property 的瀏覽器?
保留普通變數的靜態終態和合理預設值,把註冊與動畫作為增強。對關鍵內容使用 @supports 或能力偵測,並在目標瀏覽器矩陣上驗證首屏、主題與減少動效路徑。