CSS Anchor Positioning 完整教學:用原生 CSS 打造 Tooltip 和 Dropdown 不再需要 JavaScript
你有沒有遇過這種情況:為了一個小小的 tooltip,結果引入了 Popper.js 或 Floating UI,然後 bundle size 莫名多了 30KB?說實話,我以前也是這樣,直到 CSS Anchor Positioning 出現,整個遊戲規則都變了。
什麼是 CSS Anchor Positioning?
CSS Anchor Positioning 是 CSS 的原生錨點定位機制,讓你可以用純 CSS 把一個元素「錨定」在另一個元素旁邊。不需要 JavaScript 計算位置、不需要監聽 scroll 事件、不需要第三方函式庫。瀏覽器幫你搞定一切。
簡單來說,它解決了前端開發者多年來的痛點:「怎麼讓 tooltip、dropdown、popover 精確地出現在目標元素旁邊?」以前我們需要 JavaScript 去算位置,現在只要幾行 CSS 就搞定。
核心觀念:anchor-name 與 position-anchor
整個 Anchor Positioning 的運作建立在兩個核心屬性上:
anchor-name:定義錨點元素的名稱position-anchor:指定要錨定到哪個錨點
程式碼長這樣:
.trigger {
anchor-name: --my-tooltip;
}
.tooltip {
position: fixed;
position-anchor: --my-tooltip;
top: anchor(bottom);
left: anchor(center);
}就這樣!tooltip 會自動出現在 trigger 元素的正下方中間。老實說,第一次看到這個語法的時候我有點不敢相信,這也太簡潔了吧。
anchor() 函式深入解析
anchor() 函式是整個系統的核心,它接受一個位置參數,告訴瀏覽器要對齊到錨點的哪個邊:
| 參數 | 說明 |
|---|---|
anchor(top) | 錨點的上邊緣 |
anchor(bottom) | 錨點的下邊緣 |
anchor(left) | 錨點的左邊緣 |
anchor(right) | 錨點的右邊緣 |
anchor(center) | 錨點的中心點 |
你也可以用百分比,像 anchor(50%) 等同於 anchor(center),這在做微調的時候特別好用。
Step 1:打造一個基本 Tooltip
來動手做一個最基本的 tooltip。首先是 HTML 結構:
<button class="trigger" popovertarget="tip">hover me</button>
<div id="tip" popover class="tooltip">這是提示文字</div>然後是 CSS:
.trigger {
anchor-name: --tip-anchor;
}
.tooltip {
position: fixed;
position-anchor: --tip-anchor;
bottom: anchor(top);
left: anchor(center);
translate: -50% -8px;
margin: 0;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 8px 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}注意到了嗎?我搭配了 Popover API,這樣連 show/hide 的邏輯都不用寫。如果你對 CSS 的新特性有興趣,也可以看看 CSS @property 自訂屬性教學,裡面的自訂屬性搭配 anchor positioning 可以玩出很多花樣。
Step 2:打造 Dropdown 選單
Dropdown 的做法跟 tooltip 差不多,差別在於定位方向和互動模式:
.dropdown-trigger {
anchor-name: --dropdown;
}
.dropdown-menu {
position: fixed;
position-anchor: --dropdown;
top: anchor(bottom);
left: anchor(left);
width: anchor-size(width);
margin-top: 4px;
}這邊有個很實用的函式 anchor-size(width),它會讓 dropdown 的寬度跟觸發按鈕一樣寬。我自己的經驗是,很多設計稿都要求 dropdown 跟按鈕等寬,以前要用 JS 去量,現在一行 CSS 搞定。
Step 3:設定 position-try-fallbacks 避免溢出
這是 Anchor Positioning 最強大的功能之一。你有沒有遇過 tooltip 在畫面邊緣被切掉的問題?position-try-fallbacks 可以設定備用位置:
.tooltip {
position-try-fallbacks: --top, --bottom, --left, --right;
}
@position-try --top {
bottom: anchor(top);
left: anchor(center);
}
@position-try --bottom {
top: anchor(bottom);
left: anchor(center);
}瀏覽器會依序嘗試每個位置,直到找到一個不會溢出 viewport 的方案。這以前用 Floating UI 要寫一堆 middleware 的東西,現在原生就支援了。搭配 CSS @layer 層疊圖層教學 中的層疊管理,可以讓你的元件庫更有條理。
Step 4:整合 Popover API 實現完整互動
把 Anchor Positioning 跟 Popover API 結合,你可以得到完全不依賴 JavaScript 的互動式 UI 元件:
<button popovertarget="menu" class="nav-btn">選單</button>
<nav id="menu" popover class="nav-menu">
<a href="#">首頁</a>
<a href="#">關於</a>
<a href="#">聯絡</a>
</nav>Popover API 處理 show/hide 和鍵盤操作,Anchor Positioning 處理位置。兩者搭配起來就是完美的原生解決方案。
瀏覽器支援度與 Progressive Enhancement
截至 2026 年初,Chrome 125+ 和 Edge 125+ 已經完整支援 Anchor Positioning,Firefox 也在實作中。我建議用 @supports 做漸進增強:
@supports (anchor-name: --test) {
/* Anchor Positioning 樣式 */
}
@supports not (anchor-name: --test) {
/* fallback 樣式 */
}在不支援的瀏覽器上可以退回到絕對定位或繼續用 JS 方案。
跟 Popper.js / Floating UI 比較
說實話,Popper.js 和 Floating UI 在過去幾年幫了前端開發者很多忙,但有些缺點是 JavaScript 方案難以避免的:
- 增加 bundle size(Floating UI core + dom 約 15KB gzipped)
- 需要額外的事件監聽和清理
- 動態計算會造成 layout shift
- SSR 環境下可能出現閃爍
CSS Anchor Positioning 完全沒有這些問題,因為它是瀏覽器原生的渲染邏輯。如果你同時在處理色彩系統,也推薦看看 CSS color-mix() 色彩函式教學,現代 CSS 真的進步很多。
總結與建議
CSS Anchor Positioning 是近年來最讓我興奮的 CSS 新功能之一。它不只是語法糖,而是從根本上改變了我們處理定位問題的方式。建議大家現在就開始在 side project 中嘗試,等瀏覽器支援更完整的時候就能無縫切換到生產環境了。
繼續閱讀
CSS View Transitions API 完整教學:用原生 CSS 打造絲滑頁面過渡動畫
相關文章
你可能也喜歡
探索其他領域的精選好文