注意:以下新特性截至2025/08/07,只有chrome支持,safari和火狐暂未支持
参考:https://developer.mozilla.org/en-US/docs/Web/CSS/position-anchor#browser_compatibility
在过去,要实现一个下拉菜单,需要搭配js。
如今,可以利用CSS新特性实现优雅的Popover功能,做到 0 js
- popover 实现弹窗
- position-anchor 实现关联锚点元素
- position-area 实现锚点元素方向
popover + position-anchor + position-area
简单效果:
<div style="height: 100px;">
<button popovertarget="krj-menu-popover" id="krj-menu">
打开菜单
</button>
<div id="krj-menu-popover" popover>
<p>选项1</p>
<p>选项2</p>
</div>
</div>
<style>
#krj-menu {
anchor-name: --menu-anchor;
}
#krj-menu-popover {
position-anchor: --menu-anchor;
position-area: bottom;
margin: 0;
}
</style>
选项1
选项2
如果搭配tailwindcss,可以很轻松把下拉框弄得非常漂亮

人性化的定位方式 position-area
你可能在大部分组件库都用过类似这样的定位方式,特别是工具提示的组件。
锚点定位也支持类似的定位方式,引入了一种新型的定位系统叫做:position-area
这个方式比前面的实现更加便捷、更加灵活,它将锚定元素分成九宫格,并且考虑了各个位置的可扩展性,一共有 20
种可能组合,如下
先看看效果
<div>
<a
class="krj-tooltip"
href="https://www.krjojo.com/"
target="_blank"
>在上面弹出来</a
>
<div class="krj-tooltip-top">这是工具提示tooltip</div>
</div>
<style>
body {
text-align: center;
}
.krj-tooltip,
.krj-tooltip:visited,
.krj-tooltip:active {
anchor-name: --my-anchor;
line-height: 2rem;
text-decoration: none;
color: rgb(9, 128, 76);
}
.krj-tooltip:hover {
text-decoration: underline;
color: rgb(17, 97, 73);
}
.krj-tooltip-top {
position: absolute;
pointer-events: none;
opacity: 0;
transform: translateY(-2rem);
transition: all 150ms ease-in-out;
position-area: top;
position-anchor: --my-anchor;
display: inline-block;
height: 2rem;
line-height: 1rem;
padding: 1ch;
box-sizing: border-box;
background-color: #323236;
color: white;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.krj-tooltip:hover ~ .krj-tooltip-top,
.krj-tooltip:active ~ .krj-tooltip-top,
.krj-tooltip:focus-visible ~ .krj-tooltip-top {
opacity: 1;
transform: translateY(0);
}
</style>
在上面弹出来
这是工具提示tooltip
position-area: top; /* 居上,无尺寸限制 */
position-area: top center; /* 居上并且不超过锚定元素尺寸 */
position-area: top span-left; /* 居上并且左边可以扩展 */
position-area: top span-right; /* 居上并且右边可以扩展 */
position-area: left;
position-area: left center;
position-area: left span-top;
position-area: left span-bottom;
position-area: bottom center;
position-area: bottom span-left;
position-area: bottom span-right;
position-area: bottom;
position-area: right center;
position-area: right span-top;
position-area: right span-bottom;
position-area: right;
position-area: top left; /* 左上角 */
position-area: top right; /* 右上角 */
position-area: bottom left; /* 右下角 */
position-area: bottom right; /* 右下角 */
锚点尺寸 anchor-size
有时候,我们可能还需要知道锚定元素的尺寸,比如动态切换 tab 的场景
可以看到,在切换tab
时,底下的背景是可以无缝过渡的。在以前,我们要实现这样的功能,必须要借助 JS
来获取当前点击元素的尺寸和位置,但现在,只需要借助 CSS 锚点定位就能轻松实现了。
利用 anchor-size 获取锚点元素的长或宽
<nav class="krj-tab">
<a href="#HTML" name="HTML">HTML</a>
<a href="#CSS" name="CSS">CSS</a>
<a href="#JavaScript" name="JavaScript">JavaScript</a>
<a href="#React" name="React">React</a>
<a href="#Vue" name="Vue">Vue</a>
</nav>
<style>
.krj-tab a {
border: 0;
font-size: 24px;
border-radius: 100px;
padding: 10px 24px;
color: royalblue;
background: none;
overflow: hidden;
cursor: pointer;
transition: .2s;
text-decoration: none;
}
.krj-tab::after {
content: '';
position: absolute;
border-radius: 100px;
background-color: rgba(65, 105, 225, 0.2);
position-anchor: --krj-tab-anchor;
width: anchor-size(width);
height: anchor-size(height);
left: anchor(left);
top: anchor(top);
transition: .3s;
pointer-events: none;
}
.krj-tab a:target {
anchor-name: --krj-tab-anchor;
}
</style>
总结
作为css新技术在兼容性上并不成熟,目前也仅有chrome一家下放到正式环境,距离真正可实战线上使用还有不少的距离。
我一直认为,css负责全部样式动效,js负责数据逻辑处理,才是未来发展方向,
而不是一些基础常用的交互动画,也靠js来实现,完全就是重复造轮子,既浪费了开发时间,也浪费了用户带宽。
新引入的 anchor 很好的尝试解决这个问题。