前端面試:如何用 CSS anchor-scope 隔離重複元件的錨點?
題幹與適用場景
一個列表由多個相同卡片組成,每張卡片都有觸發按鈕和絕對定位的提示框。按鈕設定相同的 anchor-name,提示框以 position-anchor 引用它;結果所有提示框都貼到文件中最後一個同名錨點。請設計命名範圍、元件邊界、降級和測試。
題目聚焦 anchor-scope 對明確命名錨點的查找限制,不把它當成 Shadow DOM 隔離,也不假設所有瀏覽器都已支援 Baseline 2026 特性。
面試官考察點
- 能否說明同名錨點在未設 scope 時會按 source order 產生錯誤關聯。
- 能否區分
none、all與指定 dashed-ident 的範圍。 - 能否處理 implicit anchor、shadow tree、overflow fallback 與無支援瀏覽器。
- 能否以重複元件、可測試 DOM 和可觀測降級方案落地。
回答前需要釐清的問題
- 提示框是否必須跨越卡片祖先,還是一定位於同一卡片子樹?
- 元件是否會巢狀、使用 Shadow DOM 或被 portal 到其他容器?
- 舊瀏覽器需要保留什麼定位體驗?
- 同名 anchor 是否由設計系統統一產生,還是各頁面手寫?
- 需要哪些 overflow、鍵盤焦點和 resize 測試?
30 秒回答框架
「問題在於同名 anchor 的可見範圍沒有被限制,positioned 元素會找到 source order 最後的匹配者。我把卡片容器設為 scope root,對重複名稱使用 anchor-scope: --card-anchor 或在元件可控時使用 all,讓提示框只解析同一子樹的 anchor。再以 @supports 和普通 absolute 定位提供降級,測試巢狀卡片、portal、overflow、鍵盤和不同瀏覽器。需要保留跨子樹關聯時不亂加 scope,並以元件契約說明名稱可見性。」
分步驟深入解答
1. 先定位錯誤關聯
anchor-name 和 position-anchor 建立明確關聯。同一文件出現多個相同名稱時,未設 scope 的 positioned 元素可能解析到 source order 最後的 anchor,因此重複卡片會疊在一起。先用 DevTools 檢查 computed anchor、DOM 順序和 containing block,排除尺寸或 stacking context 問題。
2. 選擇 scope 邊界
在每個卡片容器設定 anchor-scope,scope 會把指定名稱的查找限制在該元素子樹。all 會涵蓋子樹中的 anchor names;指定 --card-anchor 則只限制該名稱,其他 anchor 名稱仍可跨出。scope 不會限制 implicit anchor,也不是通用的樣式或繼承隔離。
.card {
anchor-scope: --card-anchor;
}
.card__trigger {
anchor-name: --card-anchor;
}
.card__tip {
position: absolute;
position-anchor: --card-anchor;
position-area: block-end;
}3. 為元件定義命名契約
把 anchor name 視為元件內部介面:root、anchor、positioned element 必須位於預期子樹,且 scope 不可被任意祖先覆寫。若元件需要巢狀,為每層選擇不同名稱或在內層重新設定 scope,並在 Storybook 或元件測試中檢查 DOM 結構。
4. 處理 fallback 與能力偵測
MDN 將 anchor-scope 標為 Baseline 2026,但舊瀏覽器可能不支援。用 @supports (anchor-scope: all) 包住增強規則,未支援時回到相對容器加 absolute inset、JavaScript 計算位置或原有 tooltip 元件。fallback 必須保留焦點順序、可讀名稱和不遮擋內容。
5. 評估 portal、Shadow DOM 與 implicit anchor
anchor scope 影響 explicit anchor association;若提示框被 portal 到卡片外,可能不在 scope 子樹,應改用唯一名稱或保留既有定位方案。Shadow tree 有自己的 tree scope,仍要實測跨 shadow boundary 的可見性。不要以 anchor-scope 解決 implicit anchor 的所有問題。
6. 測試與觀測
建立多卡片、巢狀卡片、動態插入、排序變更、resize、scroll、zoom、鍵盤 focus 和 portal 的測試。檢查每個提示框的實際幾何位置、overflow、可及性樹與 fallback 命中率;記錄能力偵測結果和定位錯誤,不記錄使用者輸入內容。
高品質示範回答
「同名 anchor 在未設 scope 時可能解析到 source order 最後的元素,所以重複卡片的提示框會全部疊在一起。我會在卡片 root 設 anchor-scope: --card-anchor,trigger 設 anchor-name,提示框用 position-anchor,把 explicit lookup 限定在同一卡片子樹。若需要限制所有內部名稱可用 all,但不會影響 implicit anchor 或一般 CSS 繼承。對舊瀏覽器用 @supports 降級到相對容器與既有 tooltip 定位,並測試巢狀、portal、Shadow DOM、overflow、resize、鍵盤與排序。元件文件會列出名稱和 DOM 邊界,避免 scope 被錯誤重用。」
常見錯誤
- 只給每個元素不同 anchor-name → 元件無法封裝且動態列表難維護 → 用 scope 限制同名查找。
- 把
all當作 Shadow DOM → 仍可能有繼承、portal 或 tree scope 差異 → 分別驗證 lookup 與樣式邊界。 - 忽略 source order → 只在最後一張卡片測試而誤以為成功 → 測試多卡片與重新排序。
- 沒有 fallback → 舊瀏覽器提示框完全失位 → 用 supports 與既有 absolute 或 JS 定位降級。
- 把 scope 用在 implicit anchor → 規則不會產生預期效果 → 確認 association 是 explicit 還是 implicit。
追問及應對
anchor-scope: all 和指定名稱怎麼選?
如果元件內所有 anchor names 都應該只在本卡片解析,選 all;若只有一個名稱需要隔離,指定 --card-anchor 能避免限制其他跨元件關聯。兩者都要配合元件 DOM 契約測試。
提示框一定要在卡片子樹內嗎?
不一定。若使用 portal 或全域 overlay,scope 可能讓它看不到卡片 anchor。此時可讓 overlay 使用唯一 anchor name、傳遞幾何資料,或保留 JavaScript 定位;不要強行把 overlay 放回錯誤的 DOM 層級。
這個屬性目前能直接用在所有產品嗎?
MDN 將它標示為 Baseline 2026,W3C CSS Anchor Positioning Level 1 仍是 Working Draft。先查目標瀏覽器支援矩陣,用 @supports 和可用性測試控制漸進增強。