CSS Anchor Positioning API 可讓你在網頁開發過程中,調整元素與其他元素 (又稱「錨點」) 相對的位置。這個 API 針對許多介面功能,簡化了複雜的版面配置要求,例如選單和子選單、工具提示、選取、標籤、資訊卡、設定對話方塊等。瀏覽器內建錨定位置,可讓您建構多層式使用者介面,不必依賴第三方程式庫,進而創造出無限可能的創意體驗。
錨定位置功能自 Chrome 125 版起開放使用。
核心概念:錨點和位置元素
這個 API 的核心概念是錨點和位置元素之間的關係。錨點是使用 anchor-name
屬性指定為參照點的元素。位置元素是指使用 position-anchor
屬性相對於錨點的元素,或在定位邏輯中明確使用 anchor-name
。
設定錨定廣告
建立錨點非常簡單。將 Anchor-name 屬性套用至所選元素,並指派專屬 ID。這個專屬 ID 前面必須加上雙破折號,就像 CSS 變數一樣。
.anchor-button {
anchor-name: --anchor-el;
}
指派錨點名稱後,.anchor-button
會做為錨點,用於引導其他元素的位置。您可以透過下列任一方式將這個錨點連結至其他元素:
隱式錨點
將錨點連結至其他元素的第一個方法是使用隱含錨點,如以下程式碼範例所示。position-anchor
屬性已新增至要連結至錨點的元素,並以錨點名稱 (本例中為 --anchor-el
) 為值。
.positioned-notice {
position-anchor: --anchor-el;
}
透過隱含錨點關係,您可以使用 anchor()
函式放置元素,不必在第一個引數明確指定錨點名稱。
.positioned-notice {
position-anchor: --anchor-el;
top: anchor(bottom);
}
明確錨點
或者,您也可以直接在錨定函式中使用錨定名稱 (例如 top: anchor(--anchor-el bottom
)。這稱為明確錨點,如果想讓多個元素固定在同一處,這項做法就很實用 (如需範例,請參閱下文)。
.positioned-notice {
top: anchor(--anchor-el bottom);
}
相對於錨點的位置元素
錨定定位是以 CSS 絕對位置為基礎。如要使用定位值,請在位置元素中加入 position: absolute
。接著,使用 anchor()
函式套用定位值。舉例來說,如要將錨定元素放在錨定元素左上方,請使用下列位置:
.positioned-notice {
position-anchor: --anchor-el;
/* absolutely position the positioned element */
position: absolute;
/* position the right of the positioned element at the right edge of the anchor */
right: anchor(right);
/* position the bottom of the positioned element at the top edge of the anchor */
bottom: anchor(top);
}
現在,您已將一個元素錨定在另一個元素上,如下所示:
如要使用這些值的邏輯定位,對應方式如下:
top
=inset-block-start
left
=inset-inline-start
bottom
=inset-block-end
right
=inset-inline-end
使用 anchor-center
將定位元素置中
為更輕鬆地將錨定位置元素相對於錨點的中心點置中,我們有名為 anchor-center
的新值,可用於 justify-self
、align-self
、justify-items
和 align-items
屬性。
這個範例使用 justify-self: anchor-center
將定位元素置於錨定標記上方,藉此修改上一個元素。
.positioned-notice {
position: absolute;
/* Anchor reference */
position-anchor: --anchor-el;
/* Position bottom of positioned elem at top of anchor */
bottom: anchor(top);
/* Center justification to the anchor */
justify-self: anchor-center;
}
多個錨點
元素可與多個錨點共用。因此,您可能需要設定與多個錨點相關的位置值。方法是使用 anchor()
函式,並在第一個引數中明確指出您要參照的錨點。在以下範例中,定位元素的左上角會錨定在一個錨點的右下方,而位置元素的右下角會錨定在第二個錨點的左上角:
.anchored {
position: absolute;
top: anchor(--one bottom);
left: anchor(--one right);
right: anchor(--two left);
bottom: anchor(--two top);
}
顯示位置:inset-area
除了從絕對位置設定的預設方向位置之外,錨定 API 中還提供名為插邊區域的預設版面配置機制。
插邊區域可讓您輕鬆將定位元素 (相對於個別錨點) 放置,並適用於 9 儲存格方格,且中央有錨點元素。
各種可能的內區域定位選項,顯示於 9 儲存格的格線
如要使用插邊區域而非絕對定位,請使用 inset-area
屬性,並搭配實體或邏輯值。例如:
- 正上方:
inset-area: top
或inset-area: block-start
- 左側置中:
inset-area: left
或inset-area: inline-start
- 正下方:
inset-area: bottom
或inset-area: block-end
- 右側置中:
inset-area: right
或inset-area: inline-end
如要進一步探索這些位置,請使用以下工具:
使用 anchor-size()
調整元素的大小
anchor-size()
函式是錨定定位 API 的一部分,可用於根據錨定廣告的大小 (寬度、高度或內嵌和區塊大小) 調整錨定位置元素的大小或位置。
以下 CSS 範例說明如何在 calc()
函式中使用 anchor-size(height)
,將工具提示的高度上限設為錨定標記的兩倍。
.positioned-notice {
position-anchor: --question-mark;
/* set max height of the tooltip to 2x height of the anchor */
max-height: calc(anchor-size(height) * 2);
}
使用錨點與頂層元素 (例如彈出式視窗和對話方塊)
錨點位置與 popover
等頂層元素非常良好。和<dialog>
。雖然這些元素和 DOM 子樹狀結構其餘部分會分別放置在不同的圖層中,但錨定位置可讓您返回這些元素與位置,然後以未位於頂層圖層的元素捲動。對於分層介面來說,這可說是一大利多。
在以下範例中,系統會使用按鈕觸發一組工具提示彈出式視窗。此按鈕為錨點,工具提示則是位置元素。您可以像其他錨定元素一樣,設定位置元素的樣式。在這個具體範例中,anchor-name
和 position-anchor
是按鈕和工具提示的內嵌樣式。由於每個錨點都需要不重複的錨點名稱,因此產生動態內容時,使用內嵌是最簡單的方法。
使用@position-try
調整錨定位置
取得初始錨定位置後,如果錨定標記達到所在包含區塊的邊緣,您可能需要調整位置。如要建立替代的錨點位置,您可以使用 @position-try
指令和 position-try-options
屬性。
在以下範例中,選單右側會顯示子選單。選單和子選單很適合搭配使用錨定定位 API,以及彈出式屬性,因為這類選單通常會錨定在觸發條件按鈕上。
如果該子選單的水平空間不足,可以改為移動到選單下方。做法是先設定初始位置:
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
}
接著,使用 @position-try
設定備用錨定位置:
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
最後,使用 position-try-options
將這兩者連接在一起。看起來會像這樣:
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
*/ connect with position-try options */
position-try-options: --bottom;
}
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
錨定位置自動翻轉關鍵字
如果您有基本調整 (例如從上到下或左上切換 (或兩者同時)),甚至可以略過建立自訂 @position-try
宣告的步驟,並使用瀏覽器內建支援的翻轉關鍵字 (例如 flip-block
和 flip-inline
)。下列是自訂 @position-try
宣告的獨立功能,可與彼此搭配使用:
position-try-options: flip-block, flip-inline, flip-block flip-inline;
翻轉關鍵字可以大幅簡化錨定程式碼。只要幾行程式碼,就可以建立功能完整的錨點,並設定替代位置:
#my-tooltip {
position-anchor: --question-mark;
inset-area: top;
position-try-options: flip-block;
}
position-visibility
適用於子捲動器中的錨定廣告
在某些情況下,您可能想要錨定在網頁的子捲動器內元素。在這些情況下,您可以使用 position-visibility
控制錨定標記的顯示設定。錨定廣告會在何時留在檢視畫面中?什麼時候消失?您可以使用這項功能控制這些選項。如果您想讓位置元素停留在檢視畫面中,直到錨定標記不在檢視畫面中,請使用 position-visibility: anchors-visible
:
#tooltip {
position: fixed;
position-anchor: --anchor-top-anchor;
position-visibility: anchors-visible;
bottom: anchor(top);
}
或者,您也可以使用 position-visibility: no-overflow
避免錨定標記溢出容器。
#tooltip {
position: absolute;
position-anchor: --anchor-top-anchor;
position-visibility: no-overflow;
bottom: anchor(top);
}
特徵偵測和多元填充
目前瀏覽器支援功能有限,因此建議您謹慎使用此 API。首先,您可以使用 @supports
功能查詢,直接在 CSS 中檢查支援情形。方法是以下列方式納入錨定樣式:
@supports (anchor-name: --myanchor) {
/* Anchor styles here */
}
此外,你可以使用 CSS 錨點定位 polyfill by Oddbird,將錨定定位功能添加到作用,此功能適用於 Firefox 54、Chrome 51、Edge 79 和 Safari 10。此 polyfill 支援大部分的基本錨定位置功能,但目前的實作內容不完整,而且包含部分過時的語法。您可以使用 unpkg 連結,也可以直接在套件管理員中匯入。
無障礙注意事項
雖然錨點定位 API 可允許元素相對於其他元素的位置,但本身不會建立任何有意義的語意關係。如果錨定元素和已定位元素之間確實具有語意關係 (例如位置元素是關於錨定文字的側欄註解),其中一個方法就是使用 aria-details
從錨點元素指向位置元素。螢幕閱讀器軟體仍在學習如何處理 Aria 詳細資料,但支援服務已逐漸改善。
<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
.anchor {
anchor-name: --anchor;
}
.positioned {
position: fixed;
position-anchor: --anchor;
}
如果您將錨定位置與 popover
屬性或 <dialog>
元素搭配使用,瀏覽器就會處理焦點導覽修正,確保無障礙功能能夠正確存取,因此您不必按照 DOM 順序設定彈出式視窗或對話方塊。詳情請參閱規格中的無障礙功能注意事項。
結論
這是全新的功能,我們很期待看到各位能運用這項功能創造出什麼成果。截至目前為止,我們已看過社群相當實用的用途,例如圖表中的動態標籤、連接線、註腳,以及交叉比對視覺交叉比對。因此,試用錨定廣告位置時,請與我們分享你的寶貴意見;如果你發現任何錯誤,歡迎與我們聯絡。