返回上一级

不用js也能做弹窗 下拉框 提示框?

css html

注意:以下新特性截至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,可以很轻松把下拉框弄得非常漂亮

popover

人性化的定位方式 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>

详细位置:https://anchor-tool.com/

 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 很好的尝试解决这个问题。