这篇文章发布于 2026年09月15日,星期二,10:38,归类于 JS实例。 阅读 71 次, 今日 66 次 没有评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12403
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
一、需求背景和手搓实现
富文本输入框中的某个<img>元素hover的时候出现如下图所示的黑色提示效果。

如果是传统实现,或者你让AI来实现,多半会在div容器元素上委托mouseenter和mouseleave事件,对于带三角的黑色tips效果,会使用JS动态位置,小三角会使用CSS伪元素创建。
我说的没错吧。
但是,亲们,时代变了啊,前端技术一直在不停发展的哈。
上面那套实现,虽然也能有最终的效果,但是成本、性能和代码量都不怎么行啊。
实际上,以目前的前端能力,可以零JavaScript代码实现本需求。
具体如下:
- HTML
interestfor属性实现hover悬停目标元素显隐交互,支持设置延时显示时间; - CSS锚点定位实现定位;
- CSS
border-shape属性绘制轮廓,使边框线条完美;
演示案例
您可以狠狠地点击这里:纯CSS实现黑色气泡tooltip效果demo
最终的效果如下GIF录屏示意:

相关的HTML和CSS代码如下所示:
<button class="button-mention" interestfor="tooltip">黑夜模式封面图</button> <div id="tooltip" class="mention-tooltip" popover="hint">点击 或 按Tab键插入</div>
.button-mention {
padding: 2px 8px;
font-size: 100%;
border: 0;
border-radius: 99px;
background-color: #ffffff26;
cursor: pointer;
opacity: .75;
interest-delay-start: .2s;
color: #fff;
}
.mention-tooltip {
--tooltip-shape: shape( from 5% 0%, hline to 95%, arc to 100% 21.05% of 5% 21.05% small cw, vline to 57.89%, arc to 95% 78.95% of 5% 21.05% small cw, hline to 55%, line to 50% 100%, line to 45% 78.95%, hline to 5%, arc to 0% 57.89% of 5% 21.05% small cw, vline to 21.05%, arc to 5% 0% of 5% 21.05% small cw, close );
position: fixed;
position-area: top;
width: max-content;
margin: 0 0 2px;
padding: 2px 8px 8px;
border: 0;
aspect-ratio: 4.211;
background-color: #000;
color: #fff;
font-size: 12px;
clip-path: var(--tooltip-shape);
line-height: 2;
&:interest-target {
animation: tinydown 0.2s ease-in-out;
}
}
@supports (border-shape: none) {
.mention-tooltip {
clip-path: none;
border: 1px solid #fff1;
border-shape: var(--tooltip-shape);
}
}
@keyframes tinydown {
from {
transform: translateY(-5px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
这里的tooltips效果几乎可以说是集这几年前端新特性的大成之作。
二、新特性指引与说明
此案例使用的新特性我在之前的文章都有介绍过。
这综述下:
1. interestfor交互
按钮和链接元素设置HTML interestfor属性,可以让元素在鼠标移入移出的时候,自身和目标元素产生变化。
如果目标元素是popover元素,则目标元素会自动显示与隐藏。
也就是interestfor交互中,目标元素的popover属性不是必须的。
详见此文:HTML interestfor属性与悬停popover交互效果
额外说明:
如果是点击行为交互,则只能是按钮元素与popovertarget属性,链接元素不支持。
2. popover交互
popover交互出现比较早,目前来说已经是相对成熟的技术了。
其中,本案例用到的popover="hint"则是去年才支持的新特性,其作用是,popover浮层显示的时候,不会隐藏之前的浮层,特别适合用在tooltip这种轻提示的场景。
有兴趣可以访问这里了解:HTML popover再进化 – 新增hint类型提示框
3. position-area与锚点定位
popover元素默认是屏幕居中显示的,我们这里的诉求是在按钮上方显示,需要重定位。
这是CSS锚点定位的强项了。
这里的定位比较简单固定,因此,直接一行position-area:top就可以了。
CSS锚点定位是前端必学的技术,LuLu UI组件库的定位已经全部改成CSS锚点定位了,可以节约大量的代码,也不用担心滚动嵌套,以及复杂HTML定位元素嵌套的问题。
文章见:告别JS浮层,全新的CSS Anchor Positioning锚点定位API
4. border-shape与不规则形状边框
仔细看设计图,黑色提示框一圈是有一圈浅色的边框的。
在过去,我们多使用filter: drop-shadow()多投影去模拟,但是效果只是近似,并不完美。
现在又了border-shape属性,自然天然支持。
只不过这里想要得到提示框对应的shape()函数路径参数是实现的难点。
根据我的测试,几乎所有的模型全都全军覆没。
因为shape()函数中的SVG路径语法是一个全新的语法,AI生成的代码看似有模有样,但都跑不起来。
我最终是怎么实现的呢?
让AI去生成传统SVG的提示框路径代码,然后使用我自己弄的“CSS clip-path path() to shape()函数转换工具”转换得到的。

不过由于border-shape属性特别新,Safari浏览器还没有支持。
因此,最后使用了clip-path属性兜底。
详见文章:
5. 其他一些中老登特性
width:max-content这个CSS声明支持有快10年的历史了,日常开发我们用得不多,并不是因为他不好用,而是大家习惯使用white-space:nowrap实现类似的效果。
我个人推荐使用width:max-content,会显得更高级,且遇到绝对定位拉伸场景的时候,尺寸也不会被随意改变。
aspect-ratio是一个次新的CSS属性,用来控制元素的高宽比例,可以取代具体高宽设置,让CSS代码的适应性更强。
三、如何与vibe 编程结合
如何在 vibe 编程的时候,让 AI 输出比较前沿但是效果和代码都非常好的技术实现呢?
首先第一点,也是最最重要的。
那就是开发者自己必须要知道此需求可以使用何种技术实现,也就是必须要知识广度的积累。
这就是我一直不停学习的原因。
不过,AI总是倾向于采用传统稳健的实现方法,因此,想要让他输出高级的实现方法,一定要好好调教。
首先,按照MDN官方的skills,这个一定要安装,不然AI会产生自以为是的幻觉。
不过,根据我的实操,即使有了MDN skills的学习与约束,AI还是会有很多自以为是。比方说本例中,hover显隐完全CSS就可以cover,AI生成的代码居然自己加了JS代码mouseleave隐藏,多此一举。
导致我需要刻意强调一遍。
以下是我使用国产混元4模型(最近免费)实现tooltips效果的实录。
第一轮:
下面实现
button.button-mention的tooltips效果。此效果完全采用新技术实现,没有任何JS交互的参与。
- Hover
<button>元素的显示与隐藏,使用interestfor属性实现。所有的按钮的interestfor都指向同一个元素:
<div id="mentionTooltip" class="mention-tooltip" popover="hint">点击 或 按Tab键插入</div>mentionTooltip元素使用JS动态创建,只需要插入一次,可以在第一次创建button.button-mention元素的时候执行。此元素可以放在<body>元素下。interestfor+popover只是解决了Hover显隐的问题,并未解决定位的问题。所以,还需要使用CSS锚点定位,将
#mentionTooltip定位在<button>元素的上方。CSS锚点定位已经出来了一两年时间,你这边应该实现没问题,我就不细节指导了。
- 补充一点,Hover按钮显示Tooltip,点击的时候按钮不是会消失吗?这个Tooltip无需再额外JS隐藏,因为这是浏览器内置的交互行为,懂否?不是自定义组件那套交互,千万不要自以为是,额外添加冗余代码。
- tooltips的图形效果也使用全新的技术实现。具体如下:
- 如果用户浏览器支持CSS
border-shape属性(可以使用@supports语法判断),那就使用border-shape一次性绘制到位。这个已经超出了你的能力范围,所以,核心代码我帮你写好了:
.mention-tooltip { aspect-ratio: 4.211; border: 1px solid #fff1; border-shape: shape(from 5% 0%,hline to 95%,arc to 100% 21.05% of 5% 21.05% small cw,vline to 57.89%,arc to 95% 78.95% of 5% 21.05% small cw,hline to 55%,line to 50% 100%,line to 45% 78.95%,hline to 5%,arc to 0% 57.89% of 5% 21.05% small cw,vline to 21.05%,arc to 5% 0% of 5% 21.05% small cw,close); }- 如果不支持CSS
border-shape,那就使用clip-path: 代码示意:.mention-tooltip { aspect-ratio: 4.211; clip-path: shape(from 5% 0%,hline to 95%,arc to 100% 21.05% of 5% 21.05% small cw,vline to 57.89%,arc to 95% 78.95% of 5% 21.05% small cw,hline to 55%,line to 50% 100%,line to 45% 78.95%,hline to 5%,arc to 0% 57.89% of 5% 21.05% small cw,vline to 21.05%,arc to 5% 0% of 5% 21.05% small cw,close); }
border-shape和clip-path的shape()函数代码是一样的。因此,为了节约代码,
shape()函数可以提取为CSS变量。
.mention-tooltip剩余的背景色(纯黑)和文字颜色(纯白)以及fixed定位等CSS,你就按照你的理解补充,这个不难。对应CSS写在canvas中。
最后再强调一点,此需求其实代码量很少。
有什么疑问可以提出来,如果没有疑问,帮你的实现清单给我看一下,我确认下。
第二轮:
- constants.ts 新增两个常量这个没必要。
MENTION_TOOLTIP_ID和MENTION_TOOLTIP_TEXT只会用在一个地方,没有必要提取,这是属于过度提取,反而增加了代码的复杂度。
btn.title冲突这么处理,如果浏览器支持interestfor属性,那不设置title,否则使用浏览器原生的title属性。- 显示延迟的CSS可以加,200ms足够了。
- 文案是固定的。
第三轮:
btn.title实现代码还有些问题,手动修改。done!
根据我最近的使用,混元4模型还是可以用的,大部分场景的需求是可以满足的。
不足就是思考时间太长,高端与前沿的需求还是差些火候。
不过最近免费不要钱,这些不足也是可以忍一忍的。
四、结语
简单项目AI生成的代码规整,完美,无懈可击。
然而多人合作的复杂项目,你使用A模型,我使用B模型,再加上很多开发无脑accept,时间一长,最终代码惨不忍睹,虽然也能运行,但是性能差到离谱(参见文末图片)。
我现在让AI动手编程之前,一定会让他陈列修改文件清单,评估他的实现。
差不多一大半的时间都在沟通讨论,纠正调教。
今天试用了GLM-5.3,能力比混元强,但是思考时间也长,token效果也高。
还是Claude Code好用,不过这个贵,在公司开源节流的情况下,还是需要考虑其他模型。
这周再试用下 deepseek 4.1。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12403
(本篇完)
- HTML interestfor属性与悬停popover交互效果 (0.387)
- 全新的CSS border-shape属性简介 (0.362)
- 告别JS浮层,全新的CSS Anchor Positioning锚点定位API (0.160)
- CSS锚点定位实战-鼠标跟随交互效果 (0.117)
- CSS百分比padding实现比例固定图片自适应布局 (0.103)
- Chrome 88已经支持aspect-ratio属性了,学起来 (0.103)
- CSS高宽不等图片固定比例布局的三重进化 (0.103)
- CSS小图标剪裁终极解决方案clip-path shape()函数 (0.103)
- 抢先学习大开眼界的CSS corner-shape属性 (0.103)
- CSS corner-shape与背景底纹技术 (0.103)
- 深入理解CSS的width:auto (RANDOM - 0.074)