CSS & JS Effect – Tooltip
介绍
Tooltip 长这样
它用 popup 的方式来详细描述一个主体. 比如某个 icon 代表着什么.
参考
YouTube – How To Make Tooltips With Only CSS
思路和难点
1. hover 的时候出现
我的例子中它 hidden 使用 scale 0 来实现的. hover 的时候就变大, 就出现了.
2. 定位在主体上方 (或者其它 position)
如果我们不考虑主体在屏幕的位置, 我们可以简单粗暴的定位在上方. 但如果要考虑屏幕可见度的话, 那么还需要搞一个动态 position. 比如 sometime 出现在上方, sometime 下方. 这样难度会上一个量级哦 (这篇只是简单的定位上方, 有兴趣的可以参考 Angular CDK Overlay 的做法, 它里面有计算 popup 内容的大小, 然后再开每一个 position 哪一个可以尽可能展现完内容就用哪个 position)
3. 有一个小箭头指向主体
小箭头是用 border 做的哦.
4. 简单的 animation
scale + translateY 小移动
Step by Step
HTML & Simple Style
首先是 HTML 的部分
<div class="icon-wrapper"> <i class="fa-solid fa-envelope"></i> <p class="tooltip">This is email icon</p> </div>
有些人会比较 prefer 完全用 ::after ::before 来实现. 好处是 HTML 非常干净 (参考上面的 YouTube 视频). 但我个人觉得不利于理解. 如果做封装的话我会用 ::after ::before. 但学习的话. 用 HTML 会比较好理解.
CSS Style
.icon-wrapper { i { font-size: 96px; color: pink; } .tooltip { background-color: pink; color: red; padding: 1rem 2rem; font-size: 1.5rem; border-radius: 0.5rem; } }
给点简单的 Style 看看效果先
做小箭头
小箭头是用 border 做的
.tooltip { position: relative; &::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 16px solid transparent; border-top-color: pink; } }
其原理是隐藏另外 3 边的 border, 它就变成三角形了.
效果
定位
.icon-wrapper { position: relative; .tooltip { position: absolute; bottom: calc(100% + 1rem); left: 50%; transform: translateX(-50%); width: max-content; max-width: 256px; } }
没什么难度, 只是调调角度而已
动画
最后加入动画. 它有 2 个动画, 一个是 scale 从 0 到 1, 另一个是 translateY 稍微往上滑动一点点.
.tooltip { --scale: 0; --gap: -0.5rem; bottom: calc(100% + var(--gap)); left: 50%; transform: translateX(-50%) scale(var(--scale)); transition-property: transform, bottom; transition-duration: 0.4s; transform-origin: bottom center; } &:hover .tooltip { --scale: 1; --gap: 1rem; }
由于是动态控制 transform, 所以需要使用到 CSS Variable.
最终效果
最终 CSS Style

.icon-wrapper { i { font-size: 96px; color: pink; } position: relative; .tooltip { --scale: 0; --translateY: 2rem; background-color: pink; color: red; padding: 1rem 2rem; font-size: 1.5rem; border-radius: 0.5rem; position: absolute; bottom: calc(100% + 0.75rem); left: 50%; transform: translateX(-50%) scale(var(--scale)) translateY(var(--translateY)); width: max-content; max-width: 256px; &::after { content: ''; position: absolute; left: 50%; transform: translateX(-50%); top: 100%; border: 16px solid transparent; border-top-color: pink; } transition: transform 0.4s; transform-origin: bottom center; } &:hover { .tooltip { --scale: 1; --translateY: 0; } } }
只用 ::before 和 ::afterr 实现的版本
HTML
<span class="icon-wrapper tooltip" data-tooltip="This is email icon"> <i class="fa-solid fa-envelope"></i> </span>
CSS Style

.icon-wrapper { i { font-size: 96px; color: lightblue; } } // 可以封装 .tooltip { position: relative; --scale: 0; &::before, &::after { position: absolute; bottom: calc(100% + 1rem); left: 50%; transform-origin: bottom center; transition: transform 0.4s; } &::before { content: attr(data-tooltip); display: inline-block; width: max-content; max-width: 256px; background-color: lightblue; color: blue; padding: 1rem 2rem; font-size: 1.5rem; border-radius: 0.5rem; transform: translateX(-50%) scale(var(--scale)); } &::after { content: ''; border: 16px solid transparent; border-top-color: lightblue; transform: translateX(-50%) scale(var(--scale)) translateY(100%); // 定位方式和 ::before 一样, 只是多了一个 translateY(100%) } &:hover { --scale: 1; } }
animation 和上面的有点不同, 这是因为 ::before ::after 是 sibling 不容易控制. by right 箭头应该是 tooltip message 的 child 才容易掌控.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体
2021-12-26 Figma 学习笔记 – Layout Grid
2018-12-26 Angular 学习笔记 (组件沟通的思考)