CSS如何实现渐变提示框(tooltips)

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

CSS如何实现渐变提示框(tooltips)

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

1.jpg

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

立即学习“前端免费学习笔记(深入)”;

2.jpg

这个并不是本文的重点,有兴趣的可以访问 css-tips (codepen.io)https://codepen.io/xboxyan/pen/MLJjWQ

有时候,为了突出强调产品的特点或者为了跟随设计的潮流,设计会用上渐变背景,比如 lulu UI Edge 版本中的 Tips 组件

3.jpg

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

4.jpg

那么,如何实现这类效果呢?一起来看看吧

一、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;}

为什么要用两个相同大小的容器呢? 这是为了保证接下来渐变背景在裁剪时完全吻合

5.jpg

接着其中一个裁剪成圆角矩形,另外一个裁剪成小三角,然后重叠起来就可以了

.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个点的坐标就可以了 */}

可以看到提示框完全是自适应的,实时效果如下

6.jpg

完整代码可访问 tooltips-clip-path (codepen.io)

https://codepen.io/xboxyan/pen/ExWLyKR

二、mask 遮罩

除了 clip-pathmask 也是一种思路。如果还不熟悉 mask,可以参考这一篇

奇妙的 CSS MASK (juejin.im)

https://juejin.cn/post/6846687594693001223

这里的原理如下

7.jpg

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

8.jpg

1. 万能的 gradient

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

9.jpg

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

10.gif

可以由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,利用背景的平铺特性,合理设置背景尺寸就可以了,如下

11.gif

可以看到,背景尺寸设置成 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);  -webkit-mask-position:    left top,    left 5px,    5px top;  -webkit-mask-repeat: repeat,no-repeat,no-repeat;}

是不是精简了许多?然后再把三角形的合过来就行了,可以得到如下效果

12.jpg

完整代码可访问 tooltips-mask-gradient (codepen.io)

https://codepen.io/xboxyan/pen/KKWRWOj

2. 自适应的svg

尽管做了一些优化,上面的代码量仍然非常可观,有没有更加简便的方式呢?

想到了 svg…

一般情况下,svg 路径是固定尺寸的,只能 等比缩放 ,无法做到自适应。不过基本图形是支持自适应的,可以设置百分比尺寸,比如

   

rx 可以设置矩形的圆角,当不设置 ry 时,默认与 rx  相同

这样一个 svg 是可以自适应的,在改变尺寸的情况下不会变形(注意观察圆角),如下

13.jpg

三角形就很容易了,可以用 实现

  

然后,把两段 svg 直接用作遮罩背景就行了,可以用 mask-size 和 mask-position 分别设置 尺寸位置

tips{  -webkit-mask-image: url("data:image/svg+xml,"),url("data:image/svg+xml,");  -webkit-mask-size: 10px 5px, 100% calc(100% - 5px);  -webkit-mask-repeat: no-repeat;  -webkit-mask-position: center bottom, 0 0;}

svg 用作背景需要在前面添加 data:image/svg+xml ,并且内容需要转义,详细可参考这篇文章: 

学习了,CSS中内联SVG图片有比Base64更好的形式

https://www.zhangxinxu.com/wordpress/2018/08/css-svg-background-image-base64-encode/

还是挺不错的,代码量也不多,也比较容易理解,实时效果如下

14.jpg

完整代码可访问 tooltips-mask-svg (codepen.io)

https://codepen.io/xboxyan/pen/poeVrqB

三、paint 绘制

再来介绍一种未来的解决方式, CSS paint 。关于 CSS paint,又称 “CSS 界的绘图板”,简单来说,就是用 canvas 绘图的方式来绘制背景,canvas 几乎什么都能绘制吧,所以这是一种更为通用的解决方案。想快速了解  CSS paint 的可以参考这一篇入门文章:

CSS届的绘图板CSS Paint API简介

https://www.zhangxinxu.com/wordpress/2018/11/css-paint-api-canvas/

不过目前仅支持 Chrome,兼容性如下

20.jpg

不过并不影响我们的学习,毕竟是未来的解决方案,先看看大致的语法,如下

1、首先,JS 注册模块 registerPaint

// paint-tips.jsregisterPaint('tips-bg', class {    paint(ctx, size, properties) {       // 在这里绘制背景,语法和canvas类似    }});

2、接着,JS 添加模块 CSS.paintWorklet.addModule

if (window.CSS) {    CSS.paintWorklet.addModule('paint-tips.js');}

3、最后,CSS 中使用 paint(tips-bg)

tips{  -webkit-mask-image: paint(tips-bg); /*这里作为遮罩背景使用*/}

下面就来绘制提示框了,如果仍然借助 mask ,那么问题就变成了:如何通过 canvas 绘制这样一个图形?

15.jpg

在 canvas 中,相对于 CSS 来说, 这类图形简直就是小儿科,只需要使用 lineToarc 两个指令就可以绘制了。最关键的一点是,这里的尺寸是实时渲染的,可以通过 size 来获取

关于 canvas 学习,这里推荐一下张鑫旭老师的 Canvas API中文文档,api 和 案例比 mdn 文档清晰太多

https://www.canvasapi.cn/

绘制代码如下(下面就是很普通的 canvas 代码了,其实就是几段线段连接起来,然后填充纯色)

registerPaint('tips-bg', class {    paint(ctx, size) { // ctx为绘制上下文,size为容器尺寸      const { width,height } = size; // 容器尺寸      const radius = 5; // 圆角大小      const deg = Math.PI / 2;      const edge = 5; // 三角形大小      const pos = width / 2; // 三角形位置      ctx.beginPath();      ctx.moveTo(radius,0);      ctx.lineTo(width-2*radius,0);      ctx.arc(width-radius,radius,radius,-deg,0);      ctx.lineTo(width,height-2*radius-edge);      ctx.arc(width-radius,height-radius-edge,radius,0,deg);      ctx.lineTo(pos+edge,height-edge);      ctx.lineTo(pos,height);      ctx.lineTo(pos-edge,height-edge);      ctx.lineTo(radius,height-edge);      ctx.arc(radius,height-radius-edge,radius,deg,2*deg);      ctx.lineTo(0,radius-edge);      ctx.arc(radius,radius,radius,-2*deg,-deg);      ctx.closePath();      ctx.fillStyle = '#000';      ctx.fill();   }});

实时效果如下

16.jpg

完整代码可访问 tooltips-mask-paint (codepen.io)

https://codepen.io/xboxyan/pen/JjWvxEN

另外,也可以通过 CSS 变量进行自定义,比如定义一个--r为圆角大小,--t为三角形大小


registerPaint('tips-bg', class {  static get inputProperties() { // 定义允许的自定义属性    return [      '--r',      '--t'    ]  }  paint(ctx, size, properties) { // properties为自定义属性    const radius = Number(properties.get('--r'));    const edge = Number(properties.get('--t'));    // ...  }})

可以看到绘制是实时更新的(改变圆角),无需 JS 额外处理,实时效果如下

17.gif

完整代码可访问 tooltips-mask-paint-var (codepen.io)

https://codepen.io/xboxyan/pen/JjWvVMd

四、描边效果

有时候提示框可能还会有描边的效果,比如这样的

18.jpg

这类带描边的其实以上方式都不太适用,clip-pathmask 都无法实现描边,不过有一个边框生成方案可以参考:

有意思!不规则边框的生成方案 (juejin.cn)

https://juejin.cn/post/6944892753402822686

可惜效果不是特别完美(略微模糊)

如果尺寸固定,那么可以直接使用 svg 方式,参考这篇文章:

用SVG实现一个优雅的提示框 (juejin.cn)

https://juejin.cn/post/6926353919333531661

就目前而言,确实没有比较好的实现方案(有更好的实现方式欢迎补充,我暂时想不出来了),不过如果借助 CSS paint ,那一切就都有可能了!只需要在 paint 函数中绘制边框和背景就行了

绘制代码如下

registerPaint('tips-bg', class {    paint(ctx, size) {      const { width,height } = size; // 容器尺寸      const radius = 5; // 圆角大小      const deg = Math.PI / 2;      const edge = 5; // 三角形大小      const pos = width / 2; // 三角形位置      const lineWidth = 2; // 描边宽度      ctx.beginPath();      ctx.moveTo(radius+lineWidth,lineWidth);      ctx.lineTo(width-2*radius-lineWidth,lineWidth);      ctx.arc(width-radius-lineWidth,radius+lineWidth,radius,-deg,0);      ctx.lineTo(width-lineWidth,height-2*radius-edge-lineWidth);      ctx.arc(width-radius-lineWidth,height-radius-edge-lineWidth,radius,0,deg);      ctx.lineTo(pos+edge,height-edge-lineWidth);      ctx.lineTo(pos,height-lineWidth);      ctx.lineTo(pos-edge,height-edge-lineWidth);      ctx.lineTo(radius+lineWidth,height-edge-lineWidth);      ctx.arc(radius+lineWidth,height-radius-edge-lineWidth,radius,deg,2*deg);      ctx.lineTo(lineWidth,radius+lineWidth);      ctx.arc(radius+lineWidth,radius+lineWidth,radius,-2*deg,-deg);      ctx.closePath();      const gradient = ctx.createLinearGradient(0, 0, width, 0); // 渐变背景      gradient.addColorStop(0, '#F57853');      gradient.addColorStop(1, '#F8B578');      ctx.fillStyle = gradient;       ctx.fill();      ctx.strokeStyle = '#FBF8F8'; // 绘制边框      ctx.lineWidth = lineWidth;      ctx.lineCap = 'round';      ctx.stroke();   }});
tips{  /* -webkit-mask-image: paint(tips-bg); */  background: paint(tips-bg); /*不再借助mask,纯js绘制背景,包括渐变*/}

实时效果如下

19.jpg

完整代码可访问 tooltips-paint-stroke (codepen.io)

https://codepen.io/xboxyan/pen/QWpxdVp

五、总结和说明

以上针对 tooltips 布局共介绍了3种不同类型的实现方式,分别是 clip-pathmaskCSS paint。其中 mask 的实现重点其实是CSS图形的绘制,主要有 渐变svg 两种,虽然 渐变 的写法稍微复杂一点,但是最为通用,其他方式可能换一种布局就不适用了。现在总结一下要点:

可以用多个容器重叠配合 clip-path 实现复杂的自适应效果

在使用 CSS 渐变绘制图形时,相同的形状充分利用平铺特性

svg 基本形状支持百分比尺寸,用作背景同样有效,可以使用多张背景来组合

CSS paint 是未来的最佳解决方式,也能轻易的实现描边效果

CSS paint 唯一的缺陷是兼容性不够好(现仅支持 Chrome 65+ ),但是值得学习

当然,这些方式不仅仅是实现本文的布局而已,更多的是提供一种思路,下次碰到其他的“异形布局”也能马上联想出相应的解决方案,而不是选择“切图.png”

更多编程相关知识,请访问:编程教学!!

以上就是CSS如何实现渐变提示框(tooltips)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1620821.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
网页设计css样式特效代码大全(建议收藏)
上一篇 2025年12月24日 07:17:17
css结构化伪类选择器有哪些
下一篇 2025年12月24日 07:17:33

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • css max-height属性怎么用

    max-height 属性设置元素的最大高度。 说明 该属性值会对元素的高度设置一个最高限制。因此,元素可以比指定值矮,但不能比其高。不允许指定负值。 注意:max-height 属性不包括外边距、边框和内边距。 立即学习“前端免费学习笔记(深入)”; 值描述none 默认。定义对元素被允许的最大高…

    2026年5月10日
    100
  • 修复点击时按钮抖动:CSS垂直对齐实践

    本文探讨了在Web开发中,交互式按钮(如播放/暂停按钮)在点击时发生意外垂直位移的问题。通过分析CSS样式变化对元素布局的影响,我们发现这是由于按钮不同状态下的边框样式和内边距改变,以及默认的垂直对齐行为共同作用所致。核心解决方案是利用CSS的vertical-align属性,将其设置为middle…

    2026年5月10日
    100
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    100
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    200
  • JavaScript 动态菜单点击高亮效果实现教程

    本教程详细介绍了如何使用 JavaScript 实现动态菜单的点击高亮功能。通过事件委托和状态管理,当用户点击菜单项时,被点击项会高亮显示(绿色),同时其他菜单项恢复默认样式(白色)。这种方法避免了不必要的DOM操作,提高了性能和代码可维护性,确保了无论点击方向如何,功能都能稳定运行。 动态菜单高亮…

    2026年5月10日
    200
  • html5怎么画实线_HTML5用CSS border-style:solid画元素实线边框【绘制】

    可通过CSS的border-style属性设为solid添加实线边框:一、内联样式用border:2px solid #000;二、内部样式表统一设置如div{border:1px solid #333};三、外部CSS文件定义.my-box{border:3px solid red}并引入;四、单…

    2026年5月10日
    200
  • css如何禁止滚动条

    css禁止滚动条的方法:1、完全隐藏,代码为【】;2、在不需要时隐藏,代码为【】;3、样式表方法。 本教程操作环境:windows7系统、css3版,DELL G3电脑。 1、完全隐藏 在里加入scroll=”no”,可隐藏滚动条;   立即学习“前端免费学习笔记(深入)”;…

    2026年5月10日
    000
  • 动态更新圆形进度条:JavaScript成绩计算器集成指南

    本文档旨在指导开发者如何将JavaScript成绩计算系统与动态圆形进度条集成,实现可视化展示平均成绩。我们将详细讲解如何修改现有的JavaScript代码,使其在计算出平均分后,能够动态更新圆形进度条的进度,从而提供更直观的用户体验。本文档包含详细的代码示例和注意事项,帮助开发者轻松实现这一功能。…

    2026年5月10日
    000
  • React组件中动态属性值的管理与同步:利用状态实现受控组件

    本教程旨在解决react组件中动态属性值同步使用的问题。我们将探讨如何利用react的`usestate` hook来管理组件内部状态,从而实现一个属性的值动态地影响另一个属性,并构建出可预测、易于维护的受控组件。文章将通过具体代码示例,详细阐述从初始化状态到处理状态更新的完整过程,并强调受控组件在…

    2026年5月10日
    000
  • 如何讲html和css_讲解HTML与CSS结合使用基础【基础】

    需将HTML与CSS结合使用以实现网页结构与样式的分离:HTML定义标题、段落等语义结构,CSS控制颜色、字体等外观;可通过内联样式、内部样式表或外部CSS文件引入样式,并利用类选择器和ID选择器精准应用。 如果您希望网页不仅展示内容,还能具备基本的样式和结构布局,则需要将HTML与CSS结合使用。…

    2026年5月10日
    100
  • CSS伪元素与固定背景:移动友好的实现策略

    本文深入探讨了如何利用CSS的::before伪元素、position: fixed和z-index属性,创建一种在移动设备上表现更稳定的全屏固定背景效果,以替代传统background-attachment: fixed可能存在的兼容性问题。教程将详细解析这些核心CSS概念及其在构建响应式布局中的…

    2026年5月10日
    000
  • JavaScript计算器开发:解决数值显示与初始化问题

    本教程深入探讨了使用JavaScript构建计算器时常见的数值显示异常问题,特别是由于类属性未初始化导致的`Cannot read properties of undefined`错误。我们将详细分析问题根源,并通过在构造函数中调用初始化方法来解决该问题,同时优化显示逻辑,确保计算器功能稳定且界面显…

    2026年5月10日
    000
  • HTML表单如何实现PWA支持?怎样添加离线功能?

    答案是利用Service Worker缓存资源并结合Background Sync API实现离线提交与自动同步。通过注册Service Worker缓存表单相关文件,拦截提交行为,将离线数据存入IndexedDB,并注册后台同步任务,待网络恢复后由Service Worker自动发送数据,确保提交…

    2026年5月10日
    000
  • CSS技巧:在复杂悬停效果中确保图像始终可见

    CSS技巧:在复杂悬停效果中确保图像始终可见CSS技巧:在复杂悬停效果中确保图像始终可见CSS技巧:在复杂悬停效果中确保图像始终可见CSS技巧:在复杂悬停效果中确保图像始终可见

    本教程探讨如何在包含悬停效果的CSS卡片布局中,确保图像始终显示在最顶层而不被裁剪或遮挡。通过调整HTML结构,利用CSS的position和z-index属性,以及引入pointer-events,我们将解决图像被overflow: hidden和扩展叠加层遮盖的问题,实现复杂的视觉交互效果。 在…

    2026年5月10日 用户投稿
    000
  • HTML文档如何工作?如何编辑HTML格式文件?

    HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?

    浏览器解析和渲染html的过程包括:1. 解析html构建dom树;2. 结合css构建渲染树;3. 布局计算元素位置;4. 绘制像素到屏幕。编辑html可使用记事本、vs code、sublime text等文本或代码编辑器,其中vs code因语法高亮、自动补全和插件生态成为主流选择。标准htm…

    2026年5月10日 用户投稿
    000
  • JavaScript 中使用多个 querySelector 更新页面元素

    本文旨在讲解如何在 JavaScript 的 if 语句中使用多个 querySelector 来更新不同的页面元素,并提供示例代码和注意事项,帮助开发者理解并应用此技术。通过该方法,可以根据特定条件动态修改页面内容,提升用户体验。 使用 querySelector 在 if 语句中更新多个元素 在…

    2026年5月10日
    100
  • HTTP客户端请求缓存与重用优化

    合理使用客户端缓存与连接复用可显著提升Web性能。通过Cache-Control、ETag和Last-Modified实现条件请求,避免重复传输;启用Keep-Alive并维护TCP连接池以减少握手开销;优先采用HTTP/2或HTTP/3实现多路复用与低延迟连接;针对静态资源设置长缓存,动态数据使用…

    2026年5月10日
    000
  • CodeIgniter在IIS环境下实现URL重写与index.php移除指南

    本教程详细指导如何在IIS服务器上部署的CodeIgniter应用中,移除URL中不必要的index.php。核心解决方案涉及修改CodeIgniter的config.php文件,将$config[‘index_page’]设置为空,并辅以正确的IIS web.config重…

    2026年5月10日
    100

发表回复

登录后才能评论
关注微信