我们通常会把渐变当成一种背景效果,其实 CSS 把它当作图像处理。它不像 PNG 那样自带固定的像素尺寸,而是由浏览器根据渐变函数、绘制区域和色标位置即时生成。因此,凡是能接收图像的地方,例如 background-image、border-image、mask-image 和 list-style-image,都可以使用渐变。它会随绘制区域缩放,也省去了一次图片下载。
CSS 渐变有三条基本路径:线性渐变让颜色沿直线推进,径向渐变从中心向外扩张,圆锥渐变则围绕中心旋转。三种渐变都能重复。学习时不用急着记配色,先弄清三个问题:颜色沿哪条路径变化,色标落在哪里,生成的图像又会怎样受尺寸、位置和重复规则影响。
渐变没有固有宽高。把它用作背景并保留 background-size: auto 时,浏览器会按背景定位区的大小绘制,通常就是铺满整个区域。给它设置较小的 background-size 后,它又会变成可以定位和平铺的小图块。
最简单的线性渐变只需要两个色标:
.card {
background-image: linear-gradient(#6750a4, #ffca28);
}省略方向时,浏览器会按 to bottom 处理,也就是 180deg。第一个颜色位于渐变线起点,最后一个颜色位于终点。你可以用边或象限关键词指定方向,也可以直接写角度:
.a { background: linear-gradient(to right, #2563eb, #fb923c); }
.b { background: linear-gradient(to bottom left, #2563eb, #fb923c); }
.c { background: linear-gradient(35deg, #2563eb, #fb923c); }这里的角度以元素上方为 0deg,沿顺时针增加,所以右方是 90deg,下方是 180deg。角度前面不能加 to,因此 to 45deg 无效;单位也不能省略,应该写 0deg,不能只写 0。把方向理解成渐变线指向的位置会更直观:0deg 指向上方,于是第一个颜色在下,最后一个颜色在上。

to top right 表示“指向右上象限”,并不保证渐变线穿过右上角。矩形宽高比改变时,关键词对应的实际角度也会变化;只有在正方形里,它才恰好经过角点。需要固定角度时,直接使用 deg 或 turn。
渐变线始终穿过图像中心。确定方向后,浏览器会继续计算 0% 和 100%。它先找到离目标方向最远的角点,从该角点作一条垂直于渐变线的辅助线,交点就是起点;靠近目标方向的角点按同样方法得到终点。渐变线本身可以无限延伸,0% 和 100% 只是默认的两个计算基准点。
浏览器在渐变线上算出颜色后,会把每种颜色沿垂直方向铺开。一条一维颜色序列就这样填满了整个矩形。同一个角度放进宽矩形、正方形和高矩形时,渐变线长度并不相同,所以百分比色标的实际间距也会跟着变化。
色标也能写在这两个基准点之外。-20% 位于起点之前,120% 位于终点之后,画布只会显示落在可见区域里的部分。这意味着 0% 处未必正好是第一个色标的颜色,也可能已经进入前两个色标的混合区。
.glow-line {
background: linear-gradient(
55deg,
#2563eb -25%,
#fbbf24 50%,
#2563eb 125%
);
}一个颜色色标包括颜色,以及零到两个位置:<color> <position>? <position>?。位置可以是百分比,也可以是长度。首个色标没写位置时按 0% 处理,末个色标没写时按 100% 处理。中间如果连续出现几个未定位色标,它们会均匀分布在左右两个已定位色标之间。
.spectrum {
background: linear-gradient(
90deg,
#ef4444 0%,
#f59e0b,
#22c55e 50%,
#3b82f6,
#8b5cf6 100%
);
}在这个例子里,橙色会自动落在 25%,蓝色会落在 75%。假如最后一个色标位于 60%,它的颜色会从这里延续到末端。色标也可以写到 1200px,只是画布不够宽时,超出的部分看不见。负位置同样会参与颜色计算,不过色标本身落在画布外面。
两个不同颜色落在同一点时,中间没有过渡距离,结果就是一条硬边。如果要表达完整的纯色区间,给同一种颜色写两个位置通常更清楚:
.stripes {
background: linear-gradient(
90deg,
#334155 0% 25%,
transparent 25% 50%,
#334155 50% 75%,
transparent 75% 100%
);
}
如果后一个色标的位置小于前面已经出现的最大值,浏览器不会让色标倒退,而是把它钳制到这个最大值,因此也可能形成硬边。混用 rem 和百分比时,元素尺寸一变,两者的先后顺序也可能改变。写同一个渐变时,尽量选用容易相互比较的单位。
色标可以使用任何合法的 CSS 颜色,也包括带透明通道的颜色。这里要分清淡入透明和淡入白色:透明会逐步露出下层背景,白色则会逐步盖住下层内容。
.fade-white {
background: linear-gradient(to right, rgb(200 200 200), white);
}
.fade-away {
background:
linear-gradient(to right, rgb(200 200 200), rgb(200 200 200 / 0)),
#facc15;
两个色标之间还可以单独插入一个位置,不写颜色,这就是颜色提示。默认情况下,视觉中间色出现在两色标距离的 50% 处;颜色提示可以把这个中点移到别的位置:
.hinted {
background: linear-gradient(
to right,
#111827 20%,
35%,
#e5e7eb 80%
);
}它并不是把前后两段渐变简单拼起来。浏览器会调整整段颜色的推进方式,让中间色在提示点出现,同时保持两端连续。想把某个位置锁定为确定颜色,就写颜色色标;只想改变混合节奏时,再用颜色提示。现有语法不能直接把 ease-in 一类缓动函数放进提示里。
你可以拖动角度和两个色标位置。勾选“形成硬边”后,橙色色标会移到蓝色色标所在的位置,此时两种颜色之间的过渡距离变成零。
普通渐变默认只覆盖整张渐变图像,不会自动循环。要得到多个周期,一种做法是缩小 background-size 后平铺,另一种是使用 repeating-linear-gradient(),让色标序列沿渐变线反复出现。每个重复周期的长度,就是最后一个色标位置减去第一个色标位置。
.warning-tape {
background: repeating-linear-gradient(
-45deg,
#111827 0 18px,
#facc15 18px 36px
);
}所以,末尾色标需要一个明确的位置。省略后,它会默认落在 100%,一个周期随之扩展到整条渐变线,重复效果就很难看出来。想让循环边界平滑,末尾色标还应该回到开头的颜色:
.soft-wave {
background: repeating-linear-gradient(
-45deg,
#7c3aed 0,
#fbbf24 40px,
#7c3aed 80px
);
}如果只写紫色到金色,每隔 40px 就会从金色硬切回紫色。补上位于 80px 的紫色后,周期首尾便能连续衔接。百分比位置依赖整条渐变线,容易让单个周期占满图像,所以重复线性图案通常用 px 或 rem 更直观。
径向渐变从一个中心向外扩张。最简单的写法是 radial-gradient(#7c3aed, #fbbf24),中心默认为 center。形状通常会跟随画布的宽高比:矩形里是椭圆,正方形里是圆。需要确定形状时,可以显式写出 circle 或 ellipse。
圆形使用一个非负长度表示半径。椭圆需要两个非负尺寸,先写横轴,再写纵轴:
.circle { background: radial-gradient(60px circle, #fff, #2563eb); }
.ellipse { background: radial-gradient(60px 35px, #fff, #2563eb); }椭圆尺寸可以使用百分比,也能把长度和百分比混在一起。圆形半径不能用百分比,因为浏览器无法确定它应该相对宽度还是高度计算。除了显式尺寸,还可以使用四个关键词:
closest-side:触达离中心最近的边;farthest-side:触达离中心最远的边;closest-corner:触达最近角;farthest-corner:触达最远角,也是默认值。椭圆使用角点关键词时,边界要经过目标角,同时保留由对应边关键词推导出的宽高比。尺寸关键词不能和长度拼在一起,所以 closest-side 30px 无效。
中心位置写在 at 后面,用法和背景定位相近,可以组合关键词、长度与百分比:
.spotlight {
background: radial-gradient(
closest-corner circle at 30% 65%,
#fff7ed,
#fb7185 55%,
#312e81
);
}
浏览器会沿一条从中心向右的渐变射线计算径向渐变。0% 位于中心,100% 是射线与指定圆或椭圆边界的交点。射线上的颜色不会沿平行直线铺开,而会扩展成一组按比例放大的同心圆或同心椭圆。
径向色标的位置规则和线性色标相同,包括省略位置、双位置和颜色提示。不过径向渐变在 100% 之外仍可能明显可见。如果径向形状小于画布,最后一个色标的颜色会继续填充外部;我们也可以主动把色标写到形状之外。
.radial-overflow {
background: radial-gradient(
50px circle at center,
#7c3aed 0,
#22c55e 40px,
#fbbf24 80px
);
}这里的名义半径虽然只有 50px,颜色仍会计算到 80px。负色标位于中心之前,会影响中心点最终呈现的混合色,但负半轴本身不会显示出来。
尺寸为零时,径向渐变会进入退化状态。半径为零的圆会按一个极小的正半径处理,画面通常只剩末尾色标的颜色。零宽椭圆配合长度色标,可能看起来像以竖直轴为镜像轴的水平线性渐变;换成百分比色标后,位置会解析为 0,结果往往是纯色。零高椭圆通常也只显示末尾色标色。这些边界情形曾长期存在渲染差异,不适合承担关键视觉效果,实际使用时应给尺寸设定可靠的下限。
不要把“零宽椭圆能模拟镜像渐变”当成常规技巧。它依赖极端几何和浏览器的退化处理。生产代码更适合用两个线性渐变、伪元素或遮罩,把效果明确地写出来。
repeating-radial-gradient() 会沿渐变射线重复色标周期,可以用来绘制波纹、靶心和同心环。要让重复真正显现出来,通常得显式限制径向形状的尺寸。沿用默认的 farthest-corner 时,第一个周期往往已经延伸到最远角,画布里便没有空间显示后续周期。
.ripples {
background: repeating-radial-gradient(
80px 45px at 35% 60%,
#7c3aed 0 12px,
#fbbf24 12px 24px,
#22c55e 24px 36px,
#7c3aed 36px 48px
);
}首尾颜色不同,周期连接处就会硬切。想得到柔和波纹,末尾颜色应该回到开头的颜色。和重复线性渐变不同,尺寸明确的径向渐变使用百分比色标仍然很实用:百分比相对射线终点计算,而终点之外的区域仍然可见,因此后续周期可以继续向外扩张。
圆锥渐变沿角度绕着中心变色。同一角度上的整条射线颜色相同,因此它很适合绘制色相盘、仪表盘、扇区和放射纹。
.wheel {
background: conic-gradient(
red,
magenta,
blue,
aqua,
lime,
yellow,
red
);
border-radius: 50%;
}它默认从顶部的 0deg 开始,顺时针走一圈,在 360deg 回到起点。from <angle> 会旋转整个渐变,所有色标跟着一起偏移;at <position> 则用来移动中心:
.gauge {
background: conic-gradient(
from 45deg at 65% 35%,
#22c55e 0 35%,
#facc15 40% 60%,
#ef4444 65% 100%
);
}圆锥色标只接受角度或百分比,不能使用长度。25% 是一圈的四分之一,也就是 90deg。给一种颜色写两个角位置,就能得到纯色扇区。相邻扇区在同一点连接时形成硬边,留出一段距离则会产生柔和过渡。

圆锥渐变生成的仍然是矩形图像,不会因为颜色绕了一圈就自动变圆。制作饼图或色相环时,还需要配合 border-radius: 50%、clip-path 或遮罩。普通圆锥渐变若要在 360° 与 0° 之间平滑衔接,末尾颜色最好和开头一致。
repeating-conic-gradient() 会把一个角度周期重复到整圈。例如,前 10 度用深色、后 10 度用浅色,20 度一个周期,就能形成均匀的放射纹:
.burst {
background: repeating-conic-gradient(
from -10deg,
#1e3a8a 0 10deg,
#bfdbfe 10deg 20deg
);
}圆锥渐变也能用来画棋盘。先定义四个象限,再缩小背景图像并平铺:
.checker {
background-image: conic-gradient(
#334155 0 25%,
#f8fafc 25% 50%,
#334155 50% 75%,
#f8fafc 75% 100%
);
background-size: 32px 32px;
}重复圆锥渐变的周期会绕回顶部,浏览器可以跨过 360°/0° 边界继续混合颜色。不过,如果第一个颜色被明确写成 0 5deg 的纯色段,跨界混合就没有了空间,顶部会出现硬接缝。设计连续放射纹时,要把第一个和最后一个色标放在一起检查,因为它们正好位于同一条接缝的两侧。
既然渐变是图像,它就能像普通背景图一样使用 background-size、background-position 和 background-repeat。例如,把一张硬边径向渐变缩成小图块再平铺,就能得到圆点纸:
.dot-paper {
background:
radial-gradient(circle, rgb(15 23 42 / .18) 0 5px, transparent 5px)
0 0 / 24px 24px repeat,
#fff7ed;
}在 CSS 背景列表里,写在最前面的图层位于最上方。叠加多个渐变时,可以把画面拆成光照层、纹理层和底色层:
.curtain {
background-image:
linear-gradient(0deg, rgb(255 210 180 / .35), transparent 70%),
repeating-linear-gradient(88deg,
transparent 0 18px,
rgb(80 7 20 / .55) 22px 34px,
这段代码的第一层负责底部柔光,第二层和第三层用不同周期制造不规则褶皱。每一层只处理一个视觉问题,调整时也更省事:想让褶皱更密,只需修改尺寸;想移动亮部,只需调整色标,不必重新制作位图。
渐变并不适合替代所有图片。复杂插画、要求精确像素控制的纹理,或者包含大量色标的图案,往往更难维护。简单条纹、网格、光晕、遮罩和可以参数化的图案,则很适合交给渐变。若通过自定义属性让渐变运动,还要处理 prefers-reduced-motion,为不希望看到动画的用户关闭效果。
如果重复渐变的首尾色标落在同一点,周期长度就是零,但函数仍然要求它无限重复。浏览器此时会计算一个平均渐变色,再用这个纯色填满区域。例如,紫色 0px 到金色 0px 不会形成肉眼可见的条纹,而会退化成由两种颜色共同计算出的平均色。
周期短到输出分辨率无法表现时,也可能出现类似结果。比如径向渐变的中心位于角点,同时使用 closest-side 或 closest-corner,渐变射线就可能接近零。不同浏览器处理极端亚像素周期时,可能显示末尾纯色、平均色或密集噪纹。正式设计不应依赖这些退化结果。
周期需要有明确的非零长度,而且不能短到设备像素无法表现。再把首尾色标与接缝颜色写清楚,画布尺寸或设备像素比发生变化时,结果才容易预测。
0deg 当成向右。 CSS 渐变的 0 度指向上方,向右是 90 度。to 45deg。 to 只能搭配边或象限关键词,角度要直接写数值和单位。to top right 一定经过角点。 它只确定右上象限。画布不是正方形时,实际角度还取决于宽高比。100%,肉眼便看不到重复。写渐变时,我们可以按一条清楚的顺序推导。先决定颜色沿直线、从中心向外,还是绕中心旋转;再确定方向、中心、形状和尺寸;然后安排色标,包括颜色、位置、纯色区、硬边与提示。需要重复时,明确一个非零周期,并检查首尾接缝。最后把生成结果当作图像,用背景尺寸、定位、平铺和多层叠加完成图案。
如果你能说清 0% 和 100% 在哪里、未定位色标如何分布、周期有多长,以及接缝为什么平滑或突变,写出的渐变就不再依赖反复试色。它的结果可以计算,代码也更容易维护和适配不同尺寸。