先记住这个答案
CSS 渐变色文字的原理分三步。先给元素设一个 linear-gradient 背景,然后用 background-clip: text 把背景裁切成文字的形状——背景只在文字轮廓内可见。最后把 color 设成 transparent,让文字本身的颜色消失,这样渐变就透过文字形状显示出来了。三个声明缺任何一个都不行。
background-clip: text裁出渐变文字- 文字填充需透明才能露出渐变背景
- Safari 兼容性需核对相关前缀
- 渐变方向和文字排列方向一致时效果最自然
最小可用写法
只需要三行核心声明就能看到效果。实际项目里通常还要加上 -webkit- 前缀来兼容 Safari。
.gradient-text {
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
-webkit-background-clip: text; /* Safari 兼容 */
background-clip: text;
-webkit-text-fill-color: transparent; /* Safari 兼容 */
color: transparent;
}-webkit-text-fill-color 的优先级比 color 高,Safari 里如果只写 color: transparent 可能不生效,加上这行更保险。现代 Chrome 和 Firefox 不需要前缀,但加了也不会出问题。
渐变方向和文字的关系
linear-gradient(90deg, ...) 是从左到右的渐变。如果文字是一行横排的,颜色从左到右过渡看起来很自然。如果文字换了多行,每行的起始颜色都一样,因为渐变是相对于整个元素的,不是相对于每行文字的。
想让每行文字的渐变独立,需要把每行包在单独的元素里。或者用纵向渐变 180deg,每行文字落在渐变的不同区段,看起来也有层次感。
background-size 也会影响效果。如果设了 background-size: 200% 100% 再配合 animation 改变 background-position,就能做出颜色流动的效果。
兼容性和降级策略
background-clip: text 在现代浏览器里支持得很好。Chrome、Firefox、Safari、Edge 都可以用,但 Safari 一直需要 -webkit- 前缀。
做降级的思路是:先声明一个正常的 color 值,再写 background-clip: text 和 color: transparent。不支持的浏览器会忽略 background-clip: text,color: transparent 虽然生效了但文字不可见。所以更安全的做法是用 @supports 检测。
不支持的浏览器里文字会显示为你最开始设的那个 color 值,比如黑色,至少内容不会丢失。
容易答错的地方
- 忘了设 color 为透明
- 这是最高频的错误。写了渐变背景和
background-clip: text,但color还是默认的黑色,黑色文字盖在渐变上面,完全看不到效果。面试时先说「三个声明缺一不可」再展开,不容易遗漏。 - 以为渐变是相对于每个文字的
- 渐变是相对于整个元素的 padding box 计算的,不是每个字符。一个很长的标题,左边的字偏红、右边的字偏蓝,是因为它们在渐变轴上的位置不同。如果元素很宽但文字很短,渐变可能只显示了一小段颜色范围,看起来像纯色。
面试官还会怎么问?
渐变文字能做动画吗?
可以。用 animation 改变 background-position,配合 background-size 大于 100% 的设置,就能让渐变流动。background-position 是可插值属性,过渡和动画都能平滑执行。
文字选中后变色了怎么办?
选中文字时浏览器会用默认的选中色覆盖,渐变效果会消失。用 ::selection 伪元素把选中态的背景色和文字色设为和渐变协调的颜色。或者干脆设成 ::selection { -webkit-text-fill-color: white; background: #333; } 这样的统一配色。
暗色模式下渐变文字需要注意什么?
渐变色和页面背景的对比度必须满足无障碍标准。亮色模式下好看的渐变色到了深色背景上可能对比度不够。建议用 @media (prefers-color-scheme: dark) 切换一组对比度更高的渐变色,或者在暗色模式下回退成纯色文字。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。