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