本篇文章给大家介绍一下使用CSS如何实现支持渐变的提示框(tooltips)。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助。

今天来看一种十分常见的交互:提示框(tooltips)。通常提示框都是纯色的,比如下面这个

这类布局实现还不算复杂,可以用一个圆角矩形和一个小三角拼接形成,设置相同的颜色就可以了

这个并不是本文的重点,有兴趣的可以访问 css-tips (codepen.io) https://codepen.io/xboxyan/pen/MLJjWQ
有时候,为了突出强调产品的特点或者为了跟随设计的潮流,设计会用上渐变背景,比如 lulu UI Edge 版本中的 Tips 组件

如果仍然采用“拼接”的方式,不可避免会出现衔接不上的问题,有明显的“割裂”感,视觉还原会大打折扣

那么,如何实现这类效果呢?一起来看看吧
一、clip-path 裁剪
clip-path 可能是很多人马上就能想到的方式。但是实际操作下来,还是会遇到很多麻烦
clip-path: path 可以支持任意形状,但是却没法实现自适应宽高
clip-path: polygon 可以实现小尖角,但是无法实现圆角
clip-path: inset 可以实现自适应圆角矩形,但是无法实现下方的小尖角
如何解决这个问题呢?其实把 2 和 3 结合起来就可以了
这里需要两个相同大小的容器,可以用 ::before 和 ::after 来代替,然后设置相同的背景色,可以通过自定义属性定义
.tips{ position: relative; --bg: linear-gradient(45deg, #ff3c41, #ff9800);}.tips::before,.tips::after{ content:''; position: absolute; width: 100%; height: 100%; left: 0; top: 0; background: var(--bg);/*完全相同的背景*/ z-index: -1;}为什么要用两个相同大小的容器呢? 这是为了保证接下来渐变背景在裁剪时完全吻合

接着其中一个裁剪成圆角矩形,另外一个裁剪成小三角,然后重叠起来就可以了
.tips::before{ clip-path: inset(0 0 5px 0 round 5px); /*round 可以设置圆角*/}.tips::after{ clip-path: polygon(calc(50% - 5px) calc(100% - 5px), calc(50% + 5px) calc(100% - 5px), 50% 100%); /* 实现小三角,只需要3个点的坐标就可以了 */}可以看到提示框完全是自适应的,实时效果如下

完整代码可访问 tooltips-clip-path (codepen.io)
https://codepen.io/xboxyan/pen/ExWLyKR
二、mask 遮罩
除了 clip-path ,mask 也是一种思路。如果还不熟悉 mask,可以参考这一篇 https://juejin.cn/post/6846687594693001223 (奇妙的 CSS MASK (juejin.im))
这里的原理如下

利用 mask ,现在的问题就转变成了:如何通过 CSS 绘制这样一个图形?

1. 万能的 gradient
没有什么图形是 CSS 渐变 绘制不出来的,这个也不例外。首先我们把这个图形进行分解,这里可以分成一个圆角矩形和一个三角形,三角形比较容易,可以通过 conic-gradient 或者 linear-gradient 绘制

圆角矩形就稍微有点麻烦了,不过还是可以分解的,如下

可以由4个径向渐变和2个线性渐变合成,用代码实现就是
tips{ -webkit-mask-image: /*4个径向渐变和2个线性渐变*/ radial-gradient(circle at 5px 5px, green 5px,transparent 0), radial-gradient(circle at 5px 5px, green 5px,transparent 0), radial-gradient(circle at 5px 5px, green 5px,transparent 0), radial-gradient(circle at 5px 5px, green 5px,transparent 0), linear-gradient(red,red), linear-gradient(blue,blue); -webkit-mask-size: 10px 10px, 10px 10px, 10px 10px, 10px 10px, 100% calc(100% - 15px), calc(100% - 10px) calc(100% - 5px) -webkit-mask-position: left top, right top, left 0 bottom 5px, right 0 bottom 5px, left 5px, 5px top; -webkit-mask-repeat: no-repeat}只要有点耐心,都可以很顺利的写出来
但是...
太长了,有很多重复的(4个radial-gradient),非常啰嗦,有没有什么办法优化呢?这里有一个技巧,碰到重复有规律的东西,可以多想想 repeat,利用背景的平铺特性,合理设置背景尺寸就可以了,如下

可以看到,背景尺寸设置成 calc(100% - 10px) 就可以达到平铺效果,代码实现就是
tips{ -webkit-mask-image: /*只需要一个径向渐变即可*/ radial-gradient(circle at 5px 5px, green 5px,transparent 0), linear-gradient(red,red), linear-gradient(blue,blue); -webkit-mask-size: calc(100% - 10px) calc(100% - 15px),/*圆角的尺寸,高度由于还需要减去三角形尺寸,所以多了5px*/ 100% calc(100% - 15px), calc(100% - 10px) calc(100% - 5px);&nbs

