CSS 錨定定位 API 簡介

CSS Anchor Positioning API 是網頁開發中的顛覆性工具,因為您可以透過原生方式,根據其他元素 (稱為錨點) 的位置調整元素位置。這個 API 簡化了許多介面功能 (例如選單和子選單、工具提示、選取項目、標籤、資訊卡、設定對話方塊等) 的複雜版面配置需求。瀏覽器內建錨定標記功能,不必依賴第三方程式庫,就能建立層層式使用者介面,盡情揮灑創意。

Chrome 125 以上版本已支援錨定位置。

瀏覽器支援

  • 125
  • 125
  • x
  • x

來源

核心概念:錨定和位置元素

這個 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-selfalign-selfjustify-itemsalign-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;
}
使用 justify-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: topinset-area: block-start
  • 左中:inset-area: leftinset-area: inline-start
  • 正下方:inset-area: bottominset-area: block-end
  • 靠右置中:inset-area: rightinset-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);
}
anchor-size 的示範

示範的螢幕截圖。

搭配彈出式和對話方塊等頂層元素使用錨定標記

錨點位置與頂層元素 (例如 popover) 使用效果十分顯著。和「<dialog>」。雖然這些元素會放在 DOM 子樹狀結構以外的其他圖層內,但錨定定位可讓您返回這些元素,並隨著不在頂層圖層的元素捲動來捲動。這對分層介面來說是一大利多。

在以下範例中,使用按鈕觸發一組工具提示彈出式視窗。按鈕是錨點,工具提示則是定位元素。您可以為定位的元素設定樣式,做法和設定其他錨定元素相同。就這個特定範例而言,anchor-nameposition-anchor 是按鈕和工具提示上的內嵌樣式。每個錨點都需要專屬的錨點名稱,因此產生動態內容時,使用內嵌是最簡單的方法。

搭配 popover 使用錨定的示範

示範的螢幕截圖。

使用 @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;
}
搭配 popover

錨定位置自動翻轉關鍵字

如果你有基本調整 (例如從上到下或從右往右滑動),甚至可以略過建立自訂 @position-try 宣告的步驟,只要使用 flip-blockflip-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-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: anchors-visible 示範

或者,您也可以使用 position-visibility: no-overflow 避免錨點溢出容器。

#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}
position-visibility: no-overflow 示範

特徵偵測和聚填

由於瀏覽器目前支援有限,建議您謹慎使用這個 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 順序顯示彈出式視窗或對話方塊。詳細查看規格中的無障礙設計注意事項。

結論

這是全新功能,我們非常期待看見您運用 Google Cloud 開發的成果。目前為止,我們已經看到社群十分有用的應用案例,例如圖表中的動態標籤、連接線、註腳,以及視覺交叉參照。因此,如果您想試用錨定定位,歡迎提供意見。如果發現任何錯誤,歡迎告訴我們

其他資訊