搶先體驗(yàn)!超強(qiáng)的 Anchor Positioning 錨點(diǎn)定位
今天小編為大家?guī)?lái)的是社區(qū)作者 chokcoco 的文章,讓我們一起來(lái)學(xué)習(xí)超強(qiáng)的 Anchor Positioning 錨點(diǎn)定位。
-
瀏覽器 URL 輸入框輸入:chrome://flags/ -
找到 Experimental Web Platform features 選項(xiàng),開(kāi)啟該功能
何為 Anchor Positioning?
-
首先,錨點(diǎn)定位,需要我們通過(guò)新的錨點(diǎn)名稱(anchor-name)來(lái)標(biāo)記元素,允許我們使用這些經(jīng)過(guò)了標(biāo)記的元素作為我們絕對(duì)定位的基準(zhǔn)目標(biāo); -
其次,我們可以在絕對(duì)定位的元素上,通過(guò)新的語(yǔ)法 anchor() 或者 anchor-size() 來(lái)錨定上述被標(biāo)記了的元素,并且可以使用被標(biāo)記元素的相應(yīng)屬性(譬如被標(biāo)記元素的 top、left、right、bottom 等) -
并且,還有一些更高級(jí)的用法,譬如錨點(diǎn)定位的 Fallback 機(jī)制,也就是可以設(shè)置多套不同的錨點(diǎn)定位規(guī)則,以適應(yīng)更為復(fù)雜的頁(yè)面布局情況
<div class="g-container">
<div class="g-use-anchor"></div>
<div class="g-anchor-element"></div>
</div>.g-container {
position: relative;
width: 50vw;
height: 50vh;
border: 2px solid #666;
display: flex;
.g-anchor-element {
width: 25vw;
height: 25vh;
border: 2px dashed #333;
margin: auto;
}
.g-use-anchor {
position: absolute;
width: 20px;
height: 20px;
background: #fc0;
border-radius: 50%;
}
}


.g-container {
position: relative;
width: 50vw;
height: 50vh;
border: 2px solid #666;
display: flex;
.g-anchor-element {
width: 25vw;
height: 25vh;
border: 2px dashed #333;
margin: auto;
anchor-name: --target;
}
.g-use-anchor {
position: absolute;
width: 20px;
height: 20px;
background: #fc0;
border-radius: 50%;
top: anchor(--target top);
left: anchor(--target left);
}
}
-
我們給 .g-anchor-element 添加了一句 CSS 代碼,anchor-name: --target,其含義為,將此元素設(shè)定為一個(gè)錨點(diǎn)元素,它的名字是 --target。
-
在 .g-use-anchor 中,新增了兩句代碼
-
top: anchor(--target top):這里的意思是,使用 name 為 --target 的錨點(diǎn)元素作為定位基準(zhǔn),并且將元素的頂部(top)對(duì)齊到錨點(diǎn)元素的頂部(top) -
left: anchor(--target left):同理,使用 name 為 --target 的錨點(diǎn)元素作為定位基準(zhǔn),并且將元素的左邊(left)對(duì)齊到錨點(diǎn)元素的左邊(left)


Anchor Positioning 錨點(diǎn)定位實(shí)戰(zhàn) -- 彈出框定位

<p class="g-container">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod, porro, <span>facere</span>, et incidunt error aliquam fugit pariatur eos labore ipsum voluptate magni culpa reiciendis optio at accusantium non! Quis, laboriosam.
Lorem ipsum dolor sit, <span>amet consectetur</span> adipisicing elit. Error commodi sequi perspiciatis ipsa veniam, aut, aliquam maiores quasi <span>adipisci tenetur </span>reiciendis dolor nihil aperiam labore, sunt qui ullam aspernatur <span>voluptate</span>.
</p>
p {
position: relative;
span {
color: deeppink;
}
&::before,
&::after {
position: absolute;
transition: 0;
opacity: 0;
}
&::before {
content: "";
top: calc(anchor(var(--target) top) + 10px);
left: calc(anchor(var(--target) left) + 5px);
border: 8px solid transparent;
border-bottom: 8px solid #000;
}
&::after {
content: "Alert Tips!";
width: 80px;
padding: 2px 4px;
font-size: 14px;
background: #fff;
border: 2px solid #000;
top: calc(anchor(var(--target) top) + 24px);
left: anchor(var(--target) left);
right: anchor(var(--target) right);
}
}
p span:nth-child(1) {
anchor-name: --anchor-1;
}
p span:nth-child(2) {
anchor-name: --anchor-2;
}
p span:nth-child(3) {
anchor-name: --anchor-3;
}
p span:nth-child(4) {
anchor-name: --anchor-4;
}
p:has(span:nth-child(1):hover) {
--target: --anchor-1;
}
p:has(span:nth-child(2):hover) {
--target: --anchor-2;
}
p:has(span:nth-child(3):hover) {
--target: --anchor-3;
}
p:has(span:nth-child(4):hover) {
--target: --anchor-4;
}
p:has(span:hover)::before,
p:has(span:hover)::after{
opacity: 1;
}
-
通過(guò) <p> 元素的兩個(gè)偽元素 ::before 和 ::after,實(shí)現(xiàn)了彈出框的框體和一個(gè)小三角形 -
給每個(gè) <span> 都設(shè)置了成了錨點(diǎn),也就是這么一段代碼:p span:nth-child(1) {anchor-name: --anchor-1;} -
關(guān)鍵來(lái)了,利用了 :has 選擇器,實(shí)現(xiàn)了當(dāng)哪個(gè) <span> 被 hover,則設(shè)置 --target 變量為當(dāng)前元素的 anchor-name,也就是實(shí)現(xiàn)了錨點(diǎn)元素的動(dòng)態(tài)變換 -
最終,只需要讓彈出框(也就是兩個(gè)偽元素),基于 --target 進(jìn)行定位即可,而 --target 元素,就是我們每次 Hover 的文字元素,那么彈框也就實(shí)現(xiàn)了動(dòng)態(tài)定位

-
top: calc(anchor(var(--target) top) + 10px):將彈框元素的頂部(top)對(duì)齊到錨點(diǎn)元素的頂部(top),再加上 10px 的向上間距 -
left: calc(anchor(var(--target) left) + 5px):將彈框元素的左邊(left)對(duì)齊到錨點(diǎn)元素的左邊(left),再加上 5px 的左間距
p span:nth-child(1) {
anchor-name: --anchor-1;
}
p span:nth-child(2) {
anchor-name: --anchor-2;
}
p span:nth-child(3) {
anchor-name: --anchor-3;
}
p span:nth-child(4) {
anchor-name: --anchor-4;
}
p:has(span:nth-child(1):hover) {
--target: --anchor-1;
}
p:has(span:nth-child(2):hover) {
--target: --anchor-2;
}
p:has(span:nth-child(3):hover) {
--target: --anchor-3;
}
p:has(span:nth-child(4):hover) {
--target: --anchor-4;
}
@for $i from 1 to 100 {
p:has(span:nth-child(#{$i}):hover) {
--target: --anchor-#{$i};
}
p span:nth-child(#{$i}) {
anchor-name: --anchor-#{$i};
}
}
Anchor Positioning 錨點(diǎn)定位實(shí)戰(zhàn) -- Tab 切換下劃線跟隨效果


<ul>
<li>下</li>
<li>劃</li>
<li>線</li>
<li>跟</li>
<li>隨</li>
<li>動(dòng)</li>
<li>畫(huà)</li>
</ul>
-
下劃線通過(guò) <ul>元素的偽元素實(shí)現(xiàn) -
給每個(gè) <li> 都設(shè)置了成了錨點(diǎn) -
利用了 :has 選擇器,實(shí)現(xiàn)當(dāng)任意一個(gè) <li> 被 hover,則設(shè)置 --target 錨點(diǎn)變量為當(dāng)前的 <li> 元素,也就是實(shí)現(xiàn)了錨點(diǎn)元素的動(dòng)態(tài)變換 -
最終,只需要讓下劃線,基于動(dòng)態(tài)的錨點(diǎn)進(jìn)行定位即可,也就是我們每次 Hover 的 li 元素,那么彈框也就實(shí)現(xiàn)下劃線動(dòng)態(tài)定位 -
給下劃線的 left 設(shè)置過(guò)渡效果 transition,實(shí)現(xiàn)跟隨動(dòng)畫(huà)效果
ul {
position: relative;
width: 700px;
display: flex;
li {
flex-grow: 1;
}
&::before {
position: absolute;
content: "";
height: 5px;
background: transparent;
bottom: 0;
left: anchor(var(--target) left);
right: anchor(var(--target) right);
transition: .3s all;
transform: scaleX(5);
}
}
ul:hover::before {
background: #000;
transform: scaleX(1);
}
@for $i from 1 to 8 {
ul:has(li:nth-child(#{$i}):hover) {
--target: --anchor-#{$i};
}
li:nth-child(#{$i}) {
anchor-name: --anchor-#{$i};
}
}

兼容性

-
瀏覽器 URL 輸入框輸入:chrome://flags/ -
找到 Experimental Web Platform features 選項(xiàng),開(kāi)啟該功能
最后
往期推薦
社區(qū)精選|Spring 中 @Qualifier 注解還能這么用?
社區(qū)精選|【動(dòng)畫(huà)進(jìn)階】神奇的 3D 磨砂玻璃透視效果
社區(qū)精選|效率max:AI讀了源碼后再教我
評(píng)論
圖片
表情
