CSS錨點定位:一個令人驚喜的功能,但也存在一些棘手的問題。雖然不像Flexbox或Grid那樣徹底改變遊戲規則,但它填補了數十年來CSS定位中的空白。然而,它也有一些獨特的特性,導致了一些令人費解的行為。本文將探討一個困擾我已久的錨點定位問題。
一個月前,我在閱讀他人使用錨點定位的案例時發現了這個問題,特別是Temani Afif關於“錨點定位和滾動驅動動畫”的文章。強烈建議您閱讀這篇文章,看看是什麼引起了我的注意。他巧妙地結合了錨點定位和滾動驅動動畫,製作了一個在進度變化時顏色也會改變的範圍滑塊。
更令人驚奇的是,他使用了兩個具有相同錨點名稱的目標元素,每個元素都附加到其對應的錨點上,如同魔法一般。如果這看起來並不那麼有趣,那麼我們應該簡要回顧一下錨點定位的工作原理。
請參閱我們的完整CSS錨點定位指南,以獲得更深入的了解。
錨點定位為CSS帶來了兩個新概念:錨點元素和目標元素。錨點是用於定位其他元素的參考元素。目標元素是相對於一個或多個錨點進行絕對定位的元素。
錨點和目標幾乎可以是任何元素,您可以將它們視為並排放置的兩個div:
<code><div>anchor</div> <div>target</div></code>
首先,我們必須使用anchor-name
屬性在CSS中註冊錨點元素:
<code>.anchor { anchor-name: --my-anchor; }</code>
然後,在絕對定位的元素上使用position-anchor
屬性將其附加到具有相同名稱的錨點。但是,要移動錨點周圍的目標,我們需要position-area
屬性。
<code>.target { position: absolute; position-anchor: --my-anchor; position-area: top right; }</code>
這很好用,但是如果我們更改標記以包含更多錨點和目標,情況就會變得複雜:
<code></code>
目標元素不會附加到其最近的錨點,而是全部堆積在DOM中最後註冊的錨點上。
anchor-scope
屬性在Chrome 131中引入,用於解決此問題。它將錨點的範圍限製到子樹,以便每個目標正確附加。但是,我不想關注此屬性,因為最初引起我注意的是Temani沒有使用它。出於某種原因,所有目標都正確附加,再次像魔法一樣。
目標通常附加到DOM中的最後一個錨點,而不是其最近的錨點,但在我們的第一個示例中,我們看到了兩個具有相同anchor-name
的錨點及其對應的附加目標。所有這些都沒有使用anchor-scope
屬性。發生了什麼?
兩個詞:包含塊。
關於錨點定位需要注意的是,它很大程度上依賴於元素包含塊的構建方式。這並非錨點定位本身固有的特性,而是絕對定位的特性。絕對定位的元素相對於其包含塊進行定位,而像top: 0px
、left: 30px
或inset: 1rem
這樣的內邊距屬性只是在包含塊邊界周圍移動元素,創建所謂的內邊距修改後的包含塊。
附加到錨點的目標沒有什麼不同,position-area
屬性在底層所做的就是更改目標的內邊距修改後的包含塊,使其緊挨著錨點。
通常,絕對定位元素的包含塊是整個視口,但可以通過任何位置屬性非static
的祖先元素(通常是relative
)來更改。 Temani利用了這一事實,為每個滑塊創建了一個新的包含塊,因此它們只能附加到其對應的錨點。如果您查看代碼,您可以在開頭找到它:
<code><div>anchor</div> <div>target</div></code>
如果我們在之前的示例中使用此策略,它們就會突然正確附加!
我們不需要使用anchor-scope
屬性將每個錨點附加到其各自的目標,而是利用瞭如何計算絕對元素的包含塊。但是,還有另一種方法,不需要任何額外的代碼。
當我同時試驗滾動驅動動畫和錨點定位並嘗試將文本氣泡腳註附加到帖子的側面時,我發現了這一點,如下所示:
邏輯上,每個腳註都是一個目標,但錨點的選擇有點棘手。我最初認為每個段落都可以作為錨點,但這意味著將有多個具有相同anchor-name
的錨點。結果:所有目標都將堆積在最後一個錨點上:
這可以通過我們之前為每個註釋創建新包含塊的方法來解決。但是,我們還可以採取另一種方法,我稱之為還原論方法。當有多個具有相同anchor-name
的錨點時,問題就出現了,因此我們將錨點的數量減少到一個,使用一個可以作為所有目標的公共錨點的元素。
在這種情況下,我們只想將每個目標定位在帖子的兩側,因此我們可以使用帖子的整個主體作為錨點,並且由於每個目標自然地在垂直軸上對齊,剩下的就是沿著水平軸移動它們:
您可以更好地檢查原始帖子是如何完成的!
anchor-scope
可能是最近發佈到瀏覽器(到目前為止,僅在Chrome 131 中)的CSS屬性,因此我們不能指望它的支持會超出預期。雖然我很想隨時隨地使用它,但在一段時間內它仍將局限於簡短的演示。這不是限制使用其他錨點定位屬性的理由,這些屬性在Chrome 125及更高版本中受支持(並希望在不久的將來在其他瀏覽器中受支持),因此我希望這些小問題可以幫助您毫無顧慮地繼續使用錨點定位。
以上是另一個錨定位怪癖的詳細內容。更多資訊請關注PHP中文網其他相關文章!