不用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

简单效果:

<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

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

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

毛毛虫
Facebook
X
LinkedIn
Email
Threads

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注