1. 别被渐变吓住:先看看这三兄弟各自擅长干什么
先直接回答一个很多新手都问过我的问题:CSS渐变到底难不难?我的答案很简单——难的不是语法,而是你没搞明白三个函数各自的服务场景。一旦你理解了线性、径向、锥形这三个家伙的分工,写渐变就不再是照着文档抄,而是像搭积木一样,想实现什么效果直接选对应的工具。
三兄弟的官方全名分别是 linear-gradient()、radial-gradient()、conic-gradient()。它们最终都会生成一张“图像”,所以凡是 CSS 里能使用背景图片 background-image 的地方,都能用渐变;能使用 mask-image、border-image 的地方,同样能塞进去。这一点非常重要,理解了这个“渐变即图像”的本质,你后面玩花活(比如流光边框、文字渐变、遮罩渐变)会畅通无阻。
很多人之所以一学就忘,是因为他们只背 background: linear-gradient(to right, red, blue) 这条公式,却不知道渐变函数背后还有大量参数可以控制,更不知道不同渐变的“坐标系”完全不同。我来打个比方:
- 线性渐变:像一支画笔蘸了两种颜料,在纸上沿一条直线方向涂过去,颜料在垂直这条直线的方向上均匀过渡。
- 径向渐变:像往水面上丢一颗石子,涟漪从一个中心点一圈圈往外扩散,颜色沿半径方向变化。
- 锥形渐变:像把一个披萨从中心切开展开,颜色绕着中心点转一圈,从0度角扫到360度角。
这三兄弟的适用场景差异很大。线性渐变适合做导航条底色、按钮光感、分割线、纯色过渡背景;径向渐变适合做光晕、聚光灯、圆球质感、模拟光照;锥形渐变适合做饼图、仪表盘、彩虹色盘、胶片感纹理。你在设计稿里看到的效果,绝大多数都能用它们组合出来。
这篇文章我会按“基础语法 → 参数细节 → 实战组合 → 踩坑经验”的顺序,把三兄弟挨个拆到位。你不需要一次全记下来,建议先通读一遍,再在项目里逐个试用。萌新的心态很重要:渐变写出来效果不对,绝大多数情况不是因为你笨,而是因为你还没掌握“色标位置”和“渐变方向”这两个核心变量,它们单独拎出来都不难,难在组合时的配合,我先带你把它们彻底拆明白。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. linear-gradient 线性渐变:大哥出马,一条直线走天下
为什么先讲线性渐变?因为它最常用,也最适合用来建立“色标(color stop)”这个概念。很多新手的第一个渐变效果就应该从它开始。
2.1 基础语法:方向与色标的组合规则
看下面这一行代码,是动画里最常见的写法:
css复制background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
拆开看有三个部分:角度 135deg,起点色标 #ff9a9e 0%,终点色标 #fecfef 100%。渐变方向是从左下角到右上角(135度方向),起始位置颜色最接近第一个色标,结束位置颜色最接近第二个色标,中间全部由浏览器自动插值过渡。
方向参数除了角度,还可以用方位词:to left、to right、to top、to bottom,组合写法如 to top left 也合法。角度和方位词的区别在于:方位词始终相对于元素边界,角度则按顺时针旋转。我个人的经验是,写直线元素(按钮、状态条)用方位词最直观,写斜向装饰背景用角度最灵活。比如按钮的悬停光效,从 to top 变成 to bottom,视觉上就会产生“光照方向翻转”的效果。
色标除了百分比,还支持固定长度单位,比如 px。优先用百分比,因为它会跟随容器宽度自适应;只有在做固定尺寸小元素(比如小徽标)时,我才用像素值直接卡位置。
这里有一个新手最容易忽略的坑:渐变方向指的是颜色变化的方向,不是“颜色走向”的意思。to right 是说从左往右变化,所以第一段颜色出现在左边。这个搞反了,整个背景都是反的,排查时容易浪费不少时间。
2.2 色标位置控制:从渐变到硬切边的思路转变
渐变过渡,说穿了就是浏览器在色标之间做颜色插值。但如果你把两个色标放在完全相同的位置,比如:
css复制background: linear-gradient(to right, #3494e6 50%, #ec6ead 50%);
这时候不会出现过渡带,而是在50%位置形成一条硬边。左边是 #3494e6,右边是 #ec6ead。这个技巧超级常用,它可以做出:分隔色块、条纹、三角形箭头、表格斑马纹,甚至伪3D立体按钮的侧面高光。
想要“既有过渡又有清晰边界”,可以把色标写成重叠范围,比如左边颜色占0%到40%,中间过渡从40%到60%,后面占满到100%。这种多色标写法看起来复杂,实际就是一条渐变中排列好多个停顿点而已,浏览器会按顺序自动补齐区间:
css复制background: linear-gradient(
to right,
#ff6b6b 0%,
#ff6b6b 25%,
#feca57 25%,
#feca57 50%,
#48dbfb 50%,
#48dbfb 75%,
#ff9ff3 75%,
#ff9ff3 100%
);
上面这段是四段色块的拼接效果,硬边之间没有渐变过渡。我自己做分区背景、进度条分段、加载动画的彩色底,都靠这个套路。
2.3 repeating-linear-gradient 让条纹背景一劳永逸
如果你需要重复的条纹,不必写一大串重复色标,使用 repeating-linear-gradient 可以定义“一个最小周期”然后平铺:
css复制background: repeating-linear-gradient(
45deg,
#f5f5f5 0px,
#f5f5f5 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
这段会生成斜向45度的灰白相间细条纹。关键点是理解“周期”:0到10px是一种颜色,10到20px是另一种颜色,20px之后自动从头再来。想改条纹粗细,直接调这些像素值,不要一个个去复制色标。
我再分享一个很实用的做法:条纹往往太规律,会显得死板,你可以叠加两个不同周期的条纹来打破节奏。比如一层 repeating-linear-gradient 做细条纹,再叠加一层透明度很低的大周期渐变,最终背景看起来会有布纹感,特别适合做页面底色或者卡片纹理。
3. radial-gradient 径向渐变:从一点荡开,光晕和立体感全靠它
径向渐变在我这里的高频使用场景有三类:按钮高光、页面光晕氛围、模拟球体质感。它的过渡方式是沿半径从圆心向外扩散,所以天然适合表达“距离感”。
3.1 语法里的四个可选参数
径向渐变的完整语法比线性多几个可选项,我给你按顺序拆:
css复制background: radial-gradient(
circle at center,
#fff 0%,
#000 100%
);
这里第一个参数是形状,circle 表示正圆,ellipse 表示椭圆(默认就是椭圆);第二个 at center 是圆心位置,支持 left/top/center/right/bottom 以及长度百分比,比如 at 20% 30%;后面的色标列表和线性渐变一样。
如果你觉得颜色过渡太生硬,还可以指定渐变“扩散的终点半径”。写法是:
css复制background: radial-gradient(
circle closest-side at center,
#fff,
#000
);
closest-side、farthest-side、closest-corner、farthest-corner 这4个关键词,控制渐变从圆心扩散到哪个位置就结束。默认是 farthest-corner,所以靠近边缘时颜色已经几乎接近终点色。想做一个“只在中心小范围发光”的效果,用 closest-side 会让光圈收得更紧。
这个参数往往是最容易被忽略的。新手只调颜色,效果总感觉“光晕太大太散”,其实把扩散终点改成 closest-side,立刻就有聚光灯那味儿了。
3.2 光晕、聚光灯和圆形按钮质感的做法
做页面顶部的氛围光,我推荐下面这种叠色写法:
css复制background:
radial-gradient(circle at 50% 0%, rgba(255, 154, 158, 0.4) 0%, transparent 60%),
radial-gradient(circle at 80% 30%, rgba(72, 219, 251, 0.3) 0%, transparent 50%),
linear-gradient(to bottom, #1a1a2e 0%, #16213e 100%);
三层背景叠在一起,视觉上就像两个角落分别有光晕渲染,整体背景不单调。这种技法我强烈建议你养成习惯:多个背景层按从上到下的顺序叠加,第一层永远在最上面。
圆形按钮的质感,则可以用两个径向渐变叠出来:
css复制background:
radial-gradient(circle at 30% 30%, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 40%),
radial-gradient(circle at center, #f6d365 0%, #fda085 100%);
上面这层在左上角做了高光,下面这层是基础颜色,视觉上按钮立刻有了立体感。不用加半像素阴影,效果比纯色加 box-shadow 更自然。
3.3 用径向渐变画纹理:网格、波点、噪点感
径向渐变不止能做光晕,还可以通过 repeating-radial-gradient 快速画出圆环波纹:
css复制background: repeating-radial-gradient(
circle at center,
#fff 0px,
#fff 5px,
#000 5px,
#000 10px
);
这种一圈圈的靶心效果,可以用来做加载动画的辅助视觉,或者棋盘类小游戏的背景格。再比如“波点”效果,可以配合背景尺寸来控制单元大小:
css复制background: radial-gradient(circle, #333 2px, transparent 2px);
background-size: 16px 16px;
第二行的 background-size 是关键。它把一个渐变图案限制在16×16的小格子里,然后整页平铺,视觉上就是整齐的圆点阵列。同理,改变成 ellipse 就能做出椭圆点阵。这种“渐变+背景尺寸平铺”的思路,基本能概括大量纯CSS纹理的生成原理。
4. conic-gradient 锥形渐变:绕圈扫色,饼图和仪表盘的平替
锥形渐变是三兄弟里最晚普及的,但它带来的视觉可能性完全不是前两个能替代的。它是围绕中心点、从0度到360度旋转着改变颜色,非常适合表达“角度”概念。
4.1 角度色标:从0度开始绕圈
基础语法如下:
css复制background: conic-gradient(
from 0deg,
#ff6b6b 0%,
#feca57 25%,
#48dbfb 50%,
#ff9ff3 75%,
#ff6b6b 100%
);
默认情况下颜色从12点方向开始顺时针旋转,如果你想调整起始角度,用 from 45deg 这样的写法。和线性/径向渐变不同的是,这里色标百分比代表的是“圆周上的角度占比”,不是长度占比。
如果你希望各个色块之间有明显的分界,方法跟前面一样:把相邻两个色标放在相同位置。比如做四段色块:
css复制background: conic-gradient(
#ff6b6b 0deg 90deg,
#feca57 90deg 180deg,
#48dbfb 180deg 270deg,
#ff9ff3 270deg 360deg
);
这种年间式的“起始角度+终止角度”写法,从2021年起主流浏览器都支持了。它比用百分比踩点维护起来更直观,我墙裂建议你用这个写法。
4.2 纯CSS饼图和环形进度:不用图表库也能出图
锥形渐变最经典的应用,就是纯CSS饼图。一个元素加一个渐变就能搞定:
css复制.pie {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(
#feca57 0% 60%,
#e0e0e0 60% 100%
);
}
60%处是数据边界,其余部分是灰色底。如果要加内圈文字,或者做圆环效果(中间掏空),就再叠加一层实心圆作为遮罩:
css复制.ring {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(
#feca57 0% 60%,
#e0e0e0 60% 100%
);
mask: radial-gradient(circle, transparent 0%, transparent 55%, #000 55%, #000 100%);
}
这行的 mask 让中间区域变成透明,看起来就是环形进度条。前端新手看到“进度条不用写JS”会觉得很神奇,但原理其实就是:数据占比 → 角度 → 色标位置,三者一一对应。
关于仪表盘式的角度范围(比如只显示-90度到90度的半圆),可以用 from 180deg 把扫描起点挪到底部,再用一个遮罩把不想要的部分裁掉。这种写法的调试成本略高,我一般建议先用数值算清楚角度,再上代码。
4.3 锥形渐变的纹理玩法:棋盘格与彩色转盘
锥形渐变不只能做饼图,配合 background-size 平铺同样能生成特殊纹理。最经典的“棋盘格”可以用四段锥形渐变实现:
css复制background: conic-gradient(
#000 0 25%,
#fff 0 50%,
#000 0 75%,
#fff 0 100%
);
background-size: 40px 40px;
结果就是黑白相间的棋盘格。想要彩色格,替换色标即可。再比如做彩虹色盘,直接用极其密集的色标就能得到平滑的彩色渐变环:
css复制background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
不用给每个色标写位置,浏览器会把它们等分整个圆周,非常适合做色轮、色盘、加载动画的旋转彩虹背景。
5. 三兄弟配合实战:这些效果我建议你直接抄作业
拆完单点语法,接下来给三个能直接用于日常项目的组合案例。这些案例不是炫技,而是真正解决“背景单调”的通用方案。
5.1 流光边框:渐变加定位,实现会动的边缘光
“流光边框”是近年来很流行的按钮效果。实现核心是:渐变作为背景,盖住一个偏移的渐变光带,然后让光带移动。我常用的一套写法如下:
css复制.btn {
position: relative;
overflow: hidden;
border: 2px solid transparent;
background: linear-gradient(#fff, #fff) padding-box,
conic-gradient(from var(--angle), #12c2e9, #c471ed, #f64f59, #12c2e9) border-box;
animation: spin 4s linear infinite;
--angle: 0deg;
}
@keyframes spin {
to { --angle: 360deg; }
}
这里第一层 linear-gradient(#fff, #fff) 是内容区底色,padding-box 让它不覆盖边框区域;第二层 conic-gradient 是动态滚动的彩色扫光,border-box 让它覆盖到边框位置。因为背景层顺序是上层覆盖下层,所以最终只有边框一圈露出彩色扫光。核心原理是“用两层背景分别渲染内容和边框”,动画驱动的是CSS自定义属性 --angle。
注意,自定义属性参与角度动画需要把它注册为渐变动画属性,否则某些浏览器不认,不过用于 conic-gradient(from var(--angle)) 的场景,现代浏览器基本可以正常工作。想更稳妥,可以换成在 @keyframes 里直接写 background-position 的方式来模拟流光移动。
5.2 数字加载动画和鼠标移入悬停效果
数字滚动加载动画,常见做法是JS更新数字,但背景层也可以同步变化。我更喜欢用一层径向渐变做“光圈扩散”作为数字的辅助背景:
css复制.loading {
position: relative;
width: 120px;
height: 120px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 60%);
animation: pulse 1.6s ease-out infinite;
}
@keyframes pulse {
0% { transform: scale(0.9); opacity: 0.8; }
100% { transform: scale(1.3); opacity: 0; }
}
这就是“涟漪光圈扩散”的经典实现。鼠标移入时想改变渐变方向,可以用 :hover 切换角度变量,比如:
css复制.card {
background: linear-gradient(var(--bg-angle, 135deg), #a18cd1, #fbc2eb);
transition: --bg-angle 0.3s;
}
.card:hover {
--bg-angle: 45deg;
}
虽然 transition 对自定义属性的支持取决于注册方式,但渐变角度的跳变在很多浏览器里本身就是即时的,用户并不会感到突兀。真正细腻的做法是用两层渐变,让悬停时通过调整 background-position 产生“光照扫过”的动效。
5.3 一个完整页面背景的组合示例
我在做落地页时经常用一套“模块化渐变”思路:先选一个基础色板,再用三兄弟分别负责页面不同区域。比如:
css复制body {
background:
radial-gradient(circle at 20% 10%, rgba(255,215,0,0.15) 0%, transparent 40%),
conic-gradient(from 180deg at 80% 20%, rgba(72,219,251,0.1), transparent 50%),
linear-gradient(160deg, #0f0c29, #302b63, #24243e);
}
第一层是左上角的暖色光晕,第二层是右下角绕圈的冷色微光,第三层是深色主底。页面既不花哨,又有明显的层次。这就是“多层背景视觉叠加”的完整呈现。
6. 我的踩坑记录和调试经验:渐变看起来简单,坑都藏在细节里
最后说说我实际项目里遇到的坑,以及沉淀下来的调试方法。这部分不是凑字数,是真的能帮你省下半天调试时间。
6.1 兼容性与语法细节:别被参数写法坑到
现代浏览器对三种渐变函数的支持已经很好了,但有几个细节容易踩:
conic-gradient(from 0deg at center)这种写法里,at center在某些旧版本浏览器里不支持,建议非必要不写默认位置。- 渐变里使用透明色时要注意,
transparent在很多浏览器里会被解析成rgba(0,0,0,0),如果把它夹在亮色中间,过渡时会经过一个灰暗的中间色。更好用的写法是在目标颜色基础上改成透明通道,比如rgba(255,255,255,0),这样过渡才会干净。 - 色标使用长度单位时,不同浏览器对
repeating-linear-gradient的周期计算即便标准一致,细节上也可能有细微差异。跨端测试时,宁可用百分比或等间距的像素值,也不要用不规整的小数。 - 渐变背景属于背景图,不是背景色。如果你只设置了
background: linear-gradient(...)但没有写background-color,在图像未加载或不支持的场景下可能露出无底色白屏。重要的按钮起码给一个纯色兜底。 - 渐变生成的是位图化图像,受设备像素比影响,在高分屏上极小尺寸的纹理可能发虚,解决办法是尽量让纹理单元不小于2px。
6.2 性能问题:不要每帧都重新绘制大面积渐变
渐变本身性能不差,但你要注意它和动画的组合方式。如果一个全屏渐变动画每秒都在改变 background,浏览器会反复重绘BG层,帧率会很难看。更好的做法是:
- 把渐变放到底层,不参与动画;动画元素单独一层。
- 如果实在要给渐变本身加动画,优先用
transform和opacity,避免重绘。比如光晕效果可以让整个背景容器做位移或缩放,而不是改渐变参数。 - 大量使用重复渐变的纹理页面上,尽量把纹理封装成
background-size固定的CSS类,不要动态修改。
移动端的经验尤其重要:一屏之内叠加超过三到五层大面积渐变,在低端机上滚动时可能卡顿。控制层数、降低渐变面积,效果立竿见影。
6.3 用浏览器DevTools调试渐变的思路
很多人不知道,Chrome和Firefox的DevTools里双击渐变背景,会弹出一个可视化的渐变编辑器。你可以直接拖动色标位置、修改颜色、调整角度,所见即所得。这个编辑器我用得比在线生成器还频繁,因为它能直接改源码再刷新,不用来回复制粘贴。
调试时我还有一个习惯:先用两个强对比色(比如红和蓝)验证位置,再替换成真实颜色。因为很多问题(位置偏了、方向反了)用相近色根本看不出来,用强对比色一眼就能定位。等位置确认无误,再换回正式配色,这办法效率极高。
另外,如果你想验证一个渐变是否真的透明、是否确实覆盖了某个区域,可以在页面上临时加一个红底div放到该元素后面,看渐变区域的透出效果。这个方法能快速排查“看似黑色实为透明”的问题。
最后再分享一个我个人的小习惯:每次做新页面,我会先在三兄弟里选一个“主角渐变”,其他元素尽量用纯色或者透明度很低的辅助渐变。主角负责记忆点,配角负责层次,页面整体不会乱。渐变写多了你会发现,真正高级的页面往往不是把彩虹色堆满全屏,而是用克制的渐变控制注意力。像“流光边框”这种效果,单独出现在一个按钮上很惊艳,全屏按钮都流光就变成了视觉噪音。把握住这个度,你的CSS渐变水平就真的入门了。
