linear-gradient()是CSS3特性,需写在background-image中并加-webkit-前缀兼容旧浏览器;方向参数用to top等新语法;径向渐变需指定shape和at位置;文字可读性需用Contrast工具检测;Canvas中需手动创建渐变遮罩。
background-image 里用 linear-gradient() 最直接
html5 本身不提供渐变语法,实际是 css3 的 linear-gradient() 或 radial-gradient() 在起作用,必须写在 css 的 background-image 里。很多人卡在写了却没效果,大概率是漏了浏览器前缀或写错语法结构。
常见错误现象:background: linear-gradient(...) 看似简洁,但部分老版 Safari(iOS 6.1–9.3)和 Android Browser 要求带 -webkit- 前缀;Chrome 26 以前、Firefox 15 以前也一样。
- 必须用
background-image,不能只用background(除非你明确覆盖全部背景属性) - 方向参数别写反:写成
to top是从下往上渐变,top(无to)是旧语法,已废弃 - 颜色停靠点建议用百分比(如
50%)或px,避免用关键词from/to—— 它们语义模糊且兼容性差
示例(安全写法):
div {
background-image: -webkit-linear-gradient(to right, #ff9a9e, #fad0c4);
background-image: linear-gradient(to right, #ff9a9e, #fad0c4);
}
径向渐变 radial-gradient() 圆心位置容易偏移
radial-gradient() 默认圆心在元素中心,但一旦指定位置(比如 at 20% 30%),不同浏览器对坐标的解析逻辑有细微差异,尤其在缩放或 flex 容器里,视觉上会“漂”。
使用场景:头像遮罩、按钮悬停高光、卡片浮层阴影过渡。
立即学习“前端免费学习笔记(深入)”;
- 圆心坐标推荐用
at left 20px top 30px这种绝对定位写法,比at 20% 30%更可控 - 不要省略形状关键字:写
radial-gradient(circle at center, ...)比radial-gradient(at center, ...)兼容性好,IE10+ 和所有现代浏览器都认 - 如果需要硬边过渡,两个相邻色标别写成
#fff 50%, #000 50%—— 应该错开 1%,比如#fff 49.9%, #000 50.1%,否则某些安卓 WebView 会渲染出白线
渐变做背景时,文字可读性常被忽略
纯色背景上加文字,对比度好算;但渐变背景从浅到深,中间一段灰蒙蒙的,color 设成黑色或白色很可能局部看不清。这不是代码 bug,是设计盲区。
- 用 Chrome DevTools 的「Contrast」检查工具(Elements → Styles 面板右上角 ?️ 图标)实时测文字与背景任意区域的对比度
- 别依赖单一文字色:可用
background-clip: text+-webkit-text-fill-color: transparent让文字直接“变成”渐变,但注意 Safari 对background-clip: text的支持需加-webkit-前缀,且 Firefox 不支持 - 更稳妥的做法是加一层半透黑/白遮罩:
background: linear-gradient(rgba(0,0,0,0.2), rgba(0,0,0,0.2)), url(...)
Canvas drawImage 渐变填充要绕过 fillStyle 限制
Canvas 本身不支持直接给 drawImage() 的图片加 CSS 渐变,想实现“图片叠加渐变蒙版”,得手动用 createLinearGradient() 配合 fillRect() 或像素级操作。
性能影响明显:每帧重绘渐变遮罩比纯 CSS 慢 3–5 倍,尤其在移动端 canvas 尺寸大时。
- 先用
ctx.drawImage(img, 0, 0)绘图,再创建渐变:const grad = ctx.createLinearGradient(0,0,0,canvas.height); grad.addColorStop(0, 'rgba(0,0,0,0)'); grad.addColorStop(1, 'rgba(0,0,0,0.6)'); - 别忘了设置
ctx.fillStyle = grad再调用ctx.fillRect(0,0,canvas.width,canvas.height) - 如果想让渐变只盖图片区域(不是全 canvas),得先
ctx.clip()裁剪出图片矩形路径,再 fill
复杂点在于:CSS 渐变能响应 resize 自动重绘,Canvas 渐变得监听 window.resize 手动清空重画——这点很容易被忽略,一缩放就露底色。










