在 CSS 中,可以通过原生语法定义三种类型的渐变图像:线性渐变、径向渐变和圆锥渐变。每类渐变又细分为重复模式和非重复模式两种形式。 虽然日常开发中渐变最常用来美化背景,但实际上所有支持使用图像的 CSS 属性(如列表项标记、边框图像等)都适用于渐变。
所谓渐变,其实就是两种或多种颜色之间连续过渡的视觉效果。比如从黄色过渡到红色时,色彩会从纯黄逐步渗入橙色调成分,最终过渡到鲜红。 渐变的平滑度和突变感,受可用空间大小及颜色停靠点(stops)设置的影响。例如,如果你让白色到黑色在 100px 内变化,每个像素的色彩会以极细腻的比例逐步增加深度,看起来就像灰阶平滑过渡。

这里有个核心概念需要记住:渐变本质上就是由 CSS 代码描述的图像。它们和 SVG、PNG、JPEG 等常规图片格式一样都可以渲染成图像,不同之处在于渐变无需加载外部资源、性能优秀,而且随意缩放不会失真。
渐变最大的特点之一是它本身并不带有固有尺寸。例如,当 background-size 属性设为 auto 时,实际上等价于 100%,也就是让渐变充满整个背景定位区域。
因此,假如你没有显式设定渐变背景的尺寸,它会默认填满全部可用空间。还要特别注意,如果使用具体长度(不是百分比)偏移渐变的背景位置,背景会默认重复平铺。
线性渐变通过一条直线方向进行颜料的流动与混合,是最常见且理解起来最直接的渐变类型。它的作用是在特定方向上让一种颜色顺滑过渡到另一种颜色。先看基础用法,帮助你快速上手创建线性渐变。
实现最基础的线性渐变,你只需指定两个颜色值。此时渐变将会默认从顶部(第一个颜色)向底部(第二个颜色)过渡。原因在于线性渐变的默认方向就是 to bottom,它等同于角度写法 180deg 或 0.5turn 等多种表示方式。
|<!DOCTYPE html> <html> <head> <style> .gradient-basic { width: 300px; height: 200px; background-image: linear-gradient(#0066ff, #ffffff); border: 1px solid #ccc
要调整渐变的方向,只需在定义渐变时指定方向即可。可以通过设置具体的角度(如 45deg、90deg、-135deg 等)或使用方向性关键词(比如 to right、to left、to top、to bottom)来改变渐变的流向。角度是以顶部为起点,顺时针计算:例如 0deg 代表从上到下,90deg 代表从左到右,180deg 代表由上到下,270deg 代表从右到左。
|.gradient-right { width: 300px; height: 150px; background-image: linear-gradient(90deg, #1a4d8c, #4a90e2); border: 1px solid #ccc; margin-bottom: 10px; } .gradient-left { width
线性渐变需要至少包含两个颜色断点。虽然这样是基础要求,这两个断点也可以使用同一种颜色。如果你的目标是在某一区域显示纯色效果,那么可以把同一个颜色声明两次,并结合 background-size 和 no-repeat 实现。这项技巧很适合做局部纯色背景。
线性渐变的标准格式如下:
|linear-gradient( [[ <angle> | to <side-or-quadrant> ],]? [ <color-stop-list> [, <color-hint>]? ]# , <color-stop-list> )
这一写法中,渐变可以选择是否设置方向,然后紧跟一个或多个颜色断点,以及可选的颜色提示,语句最后以一个颜色断点结尾。如之前介绍的,linear-gradient() 至少需要两个颜色。
关于渐变方向,有一点需要注意:如果用到 to 关键字,它只能和诸如 top、right、to top right 等方向连用,且这个方向描述的是“渐变线的终点”所在方向。例如,写作 linear-gradient(0deg, 红色, 绿色) 时,实际显示是底部为红色、顶部为绿色——这是因为 0 度指向顶部,顶部即为绿色的终点。这里有个注意点,角度写法不能和 to 混用,比如 to 45deg 是错误语法,会被浏览器忽略。渐变角度默认以顶部为 0 度,顺时针递增。
此外,需要特别指出的是,0deg 和 to top 效果一致,但 45deg 与 to top right 却并不是一样的。
在设置渐变色时,可以使用各种颜色表达方式,包括带透明度的 rgba(),以及 transparent 关键字。这允许你让某段渐变逐步淡出至完全透明。例如,下面的例子演示了浅灰色平滑过渡到白色,与浅灰色逐渐变为透明的不同效果:
|.fade-to-white { background-image: linear-gradient(to right, rgb(200, 200, 200), white); } .fade-to-transparent { background-image: linear-gradient(to right, rgba(200, 200, 200, 1),
第一个例子从浅灰色渐变到白色,而第二个例子将相同的浅灰色从完全不透明渐变到完全透明,从而允许父元素的黄色背景透过来。这就是使用透明度渐变和白色渐变的区别:透明度渐变会让背景内容显示出来,而白色渐变则会遮挡背景。
你不局限于只使用两种颜色。虽然这是允许的最小颜色数量,但你可以根据需要添加尽可能多的颜色。考虑下面的彩虹渐变:
|.rainbow { width: 500px; height: 100px; background-image: linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet); border: 1px solid #ccc;
该渐变的方向为 90 度,即水平向右延伸。这里包含了 7 个颜色节点,每个颜色通过逗号分隔。这些颜色节点默认沿着渐变的方向等距分布,起始于渐变线起点,结束于终点。渐变过渡区间会自动采用平滑的颜色混合方式,使视觉效果自然流畅。
如果没有单独指定颜色的位置值,浏览器会自动让它们平均分布。不过,我们其实可以为每个颜色添加最多两个具体的位置参数,甚至能通过颜色提示点实现对渐变过渡节奏的细致调控,从而获得更丰富的视觉表现。
颜色停止点的标准写法如下:
|[<color>] [ <length> | <percentage> ]{1,2}?
每个颜色后面可以(也可以不加)跟一个或两个位置参数。这样,你就能根据需求自定义每种颜色出现在渐变线上的具体位置,而不仅仅是默认等间距分布。
我们先用长度值来举例说明。比如,如果你希望彩虹的每种颜色每隔 25 像素出现一次,可以这样设置:
|.rainbow-positioned { background-image: linear-gradient(90deg, 红色, 橙色 25px, 黄色 50px, 绿色 75px, 蓝色 100px, 靛色 125px, 紫色 150px); }
这个渐变效果整体看起来很理想,但要注意,比如在 150 像素以后,紫色会填满剩下的所有区域。这是因为如果你没有设置末尾正好对应渐变线终点的颜色停止点,最后一个颜色就会一直延伸到线的末尾。
如果你设置的颜色停止点超过了渐变线实际的长度,渐变只会显示到可见区域的终点为止,多出来的部分不会渲染出来。例如,当最后一个颜色设在 1200px,而你的背景宽度远远小于该值时,可见的渐变会在中间某个位置,比如蓝色处就已经终止了。
在前面的例子中,我们还可以发现:第一个颜色(红色)如果没有指定具体位置,会默认位于渐变线的起点,相当于设置为0%或0px。同理,如果最后一个颜色没有给出位置,系统会自动把它放到渐变的终点。
线性渐变的颜色停止点,可以用多种长度单位设置,比如 px、em、vw 等,理论上可自由组合混用,虽然实际开发中通常建议统一。甚至可以使用负值,将停止点设置到渐变线的起点之前,此时颜色的过渡依然正常,超出部分的颜色会被裁剪掉,与渐变终点之外的处理类似。
百分比单位则是以整条渐变线长度为基准进行计算的,像 50% 表示在线的正中央。接下来我们再用彩虹渐变举例,只不过这次每个颜色的停止点都间隔渐变总长度的 10%:
|.rainbow-percent { background-image: linear-gradient(90deg, 红色, 橙色 10%, 黄色 20%, 绿色 30%, 蓝色 40%, 靛色 50%, 紫色 60%); }
你可以发现,在渐变的配置中,如果最后一个颜色断点的位置不是在终点,那么从这个断点到结束的位置,都会持续使用该颜色(例如上例中的紫色会填满剩余的区域)。与前面 25px 的案例相比,这里的各个颜色断点分布更为稀疏,不过原理类似。
此外,当部分颜色断点被明确标记了位置,而另外一些则没有时,未指定位置的那些颜色会自动平分分布到它们之间,保证整个过渡的均匀性。比如说,下面两个写法最终渲染出的渐变效果是一模一样的:
|/* 第一个示例 */ .spectrum { background-image: linear-gradient(90deg, 红色, 橙色, 黄色 50%, 绿色, 蓝色, 靛色 95%, 紫色); } /* 第二个示例 */ .spectrum { background-image: linear-gradient(90deg, 红色 0%, 橙色 25%, 黄色 50%, 绿色 65%
在这组渐变色停点中,红色与紫色由于没有明确写明具体位置,将会默认分别位于起点(0%)和终点(100%)。这样一来,其余没有标注百分比的颜色——如橙色、绿色和蓝色——就会自动分布在相邻已定义位置之间,确保过渡的平滑和均匀。例如,橙色正好位于红色(0%)和黄色(50%)中间,也就是25%处。至于绿色和蓝色,则被平均分配在黄色(50%)和靛色(95%)之间。这个区间跨度为45%,要在四种颜色中平分,产生三个等距的点,因此绿色和蓝色分别落在65%和80%位置。
另外,经常有同学会好奇,如果在渐变中将两个颜色停点放在同一个位置,会发生什么?例如:
|.spectrum { background-image: linear-gradient(90deg, 红色 0%, 橙色, 黄色 50%, 绿色 50%, 蓝色, 紫色); }
当在渐变中设置两个颜色停点在同一位置时,实际上就是让这两种颜色的转换在该特定位置瞬间完成,没有任何过渡区域。这意味着渐变在正常的混合过程中,会在这个设定的位置(比如这里的 50%)立即从前一个颜色直接切换到下一个颜色,这种效果被称为“硬颜色断点”或“硬停点”。具体来说,在上面的例子里,渐变会从橙色平滑过渡到 50% 位置的黄色,紧接着立刻切换到绿色,然后再平滑过渡到下一个停点(绿色到蓝色 66.67%),如此类推。
引入硬停点后,你可以轻松地实现分明的色带或条纹效果,这对于需要清晰分隔色块时非常实用。下面的代码就是一个典型的条纹样式案例:
|.stripes-hard { background-image: linear-gradient(90deg, 灰色 0%, 灰色 25%, 透明 25%, 透明 50%, 灰色 50%, 灰色 75%, 透明 75%, 透明 100%); }
实际上,通过为每种颜色明确指定起始和结束的停靠位置,我们能够以更简洁直观的方式实现同样的条纹效果。这种写法让 CSS 渐变的每段配色范围一目了然,条理更清晰,代码易于维护。下面展示的就是采用停点区间的表达方式,和上文实现的效果完全一致:
|.stripes-easy { background-image: linear-gradient(90deg, 灰色 0% 25%, 透明 25% 50%, 灰色 50% 75%, 透明 75% 100%); }
需要说明的是,渐变中的 0% 和 100% 这些起始和结束位置并不是必须显式写出来的,浏览器会默认自动补全。如果你觉得明确标注可以让代码更清晰易读,也可以保留它们;如果更注重代码简洁,也可以省略,这完全根据实际需求灵活选择。
另外,CSS 渐变允许你灵活组合不同写法的停止点。比如,既可以用一组指定起止范围的条纹,也可以只标记单个颜色节点,两种形式混合是没有问题的。举例来说,如果你希望一段渐变的前 1/4 和最后 1/4 部分表现为纯灰色,中间部分平滑过渡到透明,可以这样来实现:
|.stripes-mixed { background-image: linear-gradient(90deg, 灰色 0% 25%, 透明 50%, 灰色 75% 100%); }
好的,这就是当你把颜色停止点直接叠在一起时会发生的情况。但如果你把一个放在另一个之前会发生什么?比如这样:
|.spectrum { background-image: linear-gradient(90deg, 红色 0%, 橙色, 黄色, 绿色 50%, 蓝色 40%, 紫色); }
当多个颜色停止点出现在同一位置时(比如这里的蓝色),实际效果是,靠后的停止点会被自动调整到前一个已经指定的位置。在本例中,蓝色被放在绿色之后,而绿色被明确标注在 50% 位置,所以蓝色的实际位置也被强制为 50%。结果就是,在渐变中会产生一个明显的分界线——绿色和蓝色直接“无缝”切换,没有渐变过渡。
需要特别注意这一点:如果某个颜色停止点的位置比它前面任何已声明的停止点都要早,那么它会被“提升”到前一个停止点的最大指定位置。这意味着下方两个渐变的最终效果完全一致,因为第一个写法中,靛色本该在 30%,但由于前面的黄色已经在 50%,所以靛色被提到 50% 位置。
|/* 两个渐变视觉效果相同 */ .spectrum1 { background-image: linear-gradient(90deg, 红色 0%, 橙色, 黄色 50%, 绿色, 蓝色, 靛色 30%, 紫色); } .spectrum2 { background-image: linear-gradient(90deg, 红色 0%, 橙色, 黄色 50%, 靛色 50%, 紫色);
在这个例子中,靛色的颜色位置如果落在了比前面某个颜色停止点(比如黄色 50%)还要靠前,那么它会被自动推迟到上一个最大位置,也就是 50%。这样,线性渐变会先从红色平滑过渡到橙色,再过渡到黄色。当达到黄色后,颜色在 50% 位置发生突变,直接切换到靛色,然后再逐步过渡到紫色。至于绿色和蓝色,并不是完全忽略掉了,它们只是和靛色的过渡发生在“零距离”处,因此在视觉上表现为一个颜色的断裂。
出现这种现象,也解释了为什么我们在编写线性渐变时通常不建议混用不同的单位。比如,如果既用 rem 又用百分比,百分比的停止点数值实际上有可能比前面 rem 对应的位置小,这可能让颜色的顺序和预期出现偏差,导致渐变效果混乱。
之前我们重点讨论了颜色停止点,其实线性渐变还允许在任意两个停止点之间插入颜色提示(color hint)。它的语法大致如下:
|linear-gradient( [[ <angle> | to <side-or-quadrant> ],]? [ <color-stop-list> [, <color-hint>]? ]# , <color-stop-list> )
颜色提示本质上是控制相邻两个颜色之间怎样进行过渡。通常情况下,渐变是线性混合的——也就是说,两种颜色的混合区间正好落在它们各自标记位置的中间点(比如 50%)。但实际上,这个混合点完全可以通过颜色提示手动调整到我们希望的位置。因此,通过灵活设置颜色提示点,可以自定义颜色变换的速度和分布,获得更复杂的渐变效果。
下面这两段 CSS 看似不同,实际上渲染出的渐变结果完全一致:
|/* 第一种写法 */ .linear-default { background: linear-gradient( to right, rgb(0% 0% 0%) 25%, rgb(90% 90% 90%) 75% ); } /* 第二种写法(显式指定中点) */ .linear-explicit { background:
使用颜色提示,我们可以改变过渡的中点。不是在中点达到 rgb(45% 45% 45%),它可以设置在两个停止点之间的任何点。因此,下面的 CSS 会产生不同的效果:
|/* 示例一:默认线性过渡 */ .ex01 { background: linear-gradient(to right, rgb(0% 0% 0%) 25%, rgb(90% 90% 90%) 75%); } /* 示例二:在33%加一个颜色提示点 */ .ex02 { background
以上5个例子的共同点是:第一个颜色断点(黑色)全部位于25%,最后一个断点(浅灰)都放在了75%。不同点在于每个示例的“过渡区域”插入了不同位置的颜色提示点,具体差异如下:
.ex01:只有首尾两个停止点,黑到灰的渐变均匀分布在25%到75%之间;.ex02:25%后到33%都是黑色,然后才慢慢过渡到灰色,因此33%之前是纯黑,后续过渡带来的浅灰区域相对缩短;.ex03:黑色一直持续到67%,67%到75%之间迅速变浅,过渡区域被“推迟”到后面;.ex04 和 .ex05:颜色提示点和停止点重合,在这两个点之间出现明显断开,呈现出突变(几乎没有渐变效果)。需要特别说明的是,颜色提示点可以类似于“调速器”,决定颜色过渡的分布密度并影响变化速度。如果配合普通停止点使用,两者在原理和视觉上都有明显不同。例如下面做个直观对比:
|/* 案例A:直接用三个颜色停止点 */ .exA { background: linear-gradient(to right, rgb(0% 0% 0%) 25%, rgb(45% 45% 45%) 67%, rgb(90% 90% 90
你可以观察到:案例A(带3个停止点)是先线性地从黑色逐渐过渡到灰色,67%之后再进一步变浅;而案例B(带颜色提示点)即使在同样的关键位置,也会让渐变速度和混合方式产生不同结果,整体“曲线更柔”,视觉上有点类比PS里的缓动曲线。这源于CSS内部对颜色提示点采用特殊的过渡算法(带有平滑阻尼)。
虽然实际浏览器渲染时对颜色提示区间会自动做平滑曲线,开发者目前无法像动画那样自定义渐变的“缓动函数”。这种能力未来或许会开放,留意CSS规范的新动态即可。
前面介绍了怎么在渐变里放颜色停止点(stop),但这些颜色到底是沿着什么路径混合的呢?答案是:渐变线。
渐变线,就是渐变主轴的那一条直线,你可以通过设置角度来控制它的方向。比如这样:
|.understanding-gradient { background-image: linear-gradient(55deg, #4097FF, #FFBE00, #4097FF); }
这句的意思是:以 55 度的方向,从 #4097FF 过渡到 #FFBE00,然后再回到 #4097FF。渐变线总是穿过渐变区域的中心点,并根据你设定的角度水平或斜着延伸。
渐变线两头的颜色(第一个和最后一个停止点)通常不只是落在盒子边界上,很多时候甚至会超出区域——但浏览器会自动做填充,保证整个元素都被颜色覆盖。你在 CSS 里怎么设颜色断点,渐变就会从起点颜色顺着线慢慢过渡到终点颜色。
简单来说:线性渐变的主轴就是一条线,沿着这条线各段内的颜色会平滑混合,颜色带会在与渐变线垂直的方向扩展,填满整个区域。
如果区域宽高比变化,渐变线和它的过渡方式也会自适应调整,自动保证填充效果美观。这就是 CSS 线性渐变线的基本工作方式。
举个例子,回顾一下刚刚定义的渐变:
|.understanding-gradient { background-image: linear-gradient(55deg, #4097FF, #FFBE00, #4097FF); }
在刚才的例子中,起点的位置会显示 #4097FF 这个蓝色,而正中心(对应渐变线穿过整个图像的中心点)则是 #FFBE00 的黄色。终点回到 #4097FF,这样中间的黄色自然而然地落在了渐变图像的中心。这三个颜色之间,过渡都是平滑自然的。
你或许会疑惑,既然起点和终点其实是在整个图像区域的边缘甚至之外,为什么图像的左下角和右上角同样能呈现起点和终点的蓝色?其原理在于:每一个位于渐变线上的颜色位置,都会“成片”地沿着垂直于渐变线的方向扩展出去。可以想象一下,从渐变的起点和终点分别画出与渐变线垂直的直线,并在这两点之间每隔5%也画一条垂直线——实际效果就是这些线上的颜色保持一致、不会被混合,呈现均匀纯色。这些“垂直色带”共同填满了整个渐变图像,实现二维空间的颜色填充。
正因如此,CSS 的渐变总能很好地填充所有区域,无论渐变线方向如何,整个块的空间都会被颜色完整覆盖。
接下来,试想一下,如果把完全相同的渐变代码分别应用到不同形状的图像区域——比如宽幅矩形、标准正方形、高挑矩形——会发生什么?其实,每次图像尺寸变化时,渐变线的起点和终点也会自适应地调整,确保起点和终点颜色都落在图像区域的角上。例如,当区域变得更宽,渐变线的长度会随之变化,角度和交点也会自动重新计算,确保颜色填充依然连贯。类似地,高度变化时,渐变线也会旋转以适应新的宽高比,但起点/终点颜色始终能覆盖到图像的边角。
这里特别注意,我们用的是“起点和终点的颜色”,而不是简单地说“起点和终点颜色”——因为 CSS 渐变允许你把颜色断点(stop)设置在超出起点或终点的位置,比如:
|.extended-stops { background-image: linear-gradient(55deg, #4097FF -25%, #FFBE00, #4097FF 125%); }
颜色停止点的设置、起点和终点的关系、以及沿着渐变线分布颜色的方式,能够帮助我们理解当颜色停止点超出正常区间时 CSS 如何渲染渐变。从效果上看,左下角与右上角的颜色依然和我们设定的起点、终点相呼应。不过值得注意的是,如果某个颜色断点(如第一个)被设置在标准起点之外,那么渐变最前端的实际颜色会是前两个颜色断点的过渡混合。同理,终点的色彩往往也是倒数第二个和最后一个颜色断点之间渐变出来的。
接下来,我们来看一个容易让人困惑的情况。你是否还记得用 top、right 等方向关键词指定渐变方向的方法?很多时候,我们希望让渐变线朝向右上角,比如用如下 CSS 代码绘制渐变图像:
|.quadrant-gradient { background-image: linear-gradient(to top right, #4097FF -25%, #FFBE00, #4097FF); }
实际上,指定 to top right 这样的渐变方向时,CSS 生成的渐变线并不会直接穿过右上角。如果真是这样,理解起来反倒简单了!但事实上,它的行为要复杂一些。这里的 to top right,并非让渐变线连接图像中心与右上角,而是将渐变朝向图像的右上象限。
理解 CSS 是如何“计算”这个方向的,可以分以下几步:
to top right方向延伸。这种渐变生成方式会带来几个特别的现象。第一,中间那条主轴上的色彩变化,是从一个象限相邻角向另一个象限相邻角延伸。例如,右上象限下,主轴就穿过左上和右下的连线正中。第二,一旦你调整了图像的宽高比例,渐变主轴的角度也会随之自动调整,以适应新的形状——这对于响应式布局的元素尤其关键。第三,如果你的区域正好是个正方形,这时主轴逆变成与图像角线正好重合,也就实现了“穿角而过”的效果。 下面我们通过三个不同形状的图例来实际感受这些差异和特性:
|/* 宽矩形 */ .wide-quadrant { width: 400px; height: 200px; background-image: linear-gradient( to top right, purple, green 49.5%, black 50%, green 50.5%, purple );
需要注意的是,CSS 暂时还无法直接让渐变线完全精准地对准非正方形区域的某个特定角落。换句话说,如果你想让渐变正好从一个矩形的一个角延伸到另一个角,你通常需要根据容器的宽高比例来预先计算好角度,并明确在CSS中写明。有时这甚至可能需要借助 JavaScript 动态计算,特别是当元素尺寸会发生变化时。当然,如果元素的尺寸始终不变或者使用 aspect-ratio 属性(具体内容可参考第 6 章),这种计算会简单很多。
另外,虽然线性渐变会严格沿着你设定的角度方向进行色彩过渡,但如果你想实现类似“镜像反射”的渐变(即对称的渐变效果),其实是可以通过一定的技巧实现的。关于镜像渐变的更多内容,可以参见下文中介绍的径向渐变部分。
一般来说,CSS 中的渐变默认会自动适应背景区域的大小,并且只显示一次,不会重复铺满整个区域。换句话说,渐变图像会填满你应用它们的所有可用空间。
不过,你也可以通过自定义背景大小(background-size),并设置背景图像重复(background-repeat),实现渐变在区域内的多次平铺,尤其是配合使用“硬颜色断点”时,这样可以创建出很多有趣的装饰图案。例如,你可以定义两个带有明确停止点的线性渐变,分别沿竖直和水平方向排列,然后设置不同的底色,这样层叠起来就能模拟出带格子的桌布、网格等效果。下面就是一个实际的桌布样式案例:
|.tablecloth { background-image: linear-gradient(to top, transparent 1vw, rgb(0 0 0 / 0.2) 1vw), linear-gradient(to right, transparent 1vw, rgb(0 0 0 / 0.2)
除了通过设置 background-size 来确定渐变的尺寸,并配合 background-repeat 实现平铺效果外,其实还可以利用重复线性渐变(repeating-linear-gradient)来达到相同的目的。当我们在 linear-gradient 前加上 repeating,浏览器会在指定的颜色断点区间内自动重复渐变,无需手动设置平铺相关属性。也就是说,只要在渐变中设定颜色的起止位置和区间,系统就会不停地在这个区间内循环渐变。例如在本例中,断点的距离是 2vw,所以整个渐变会以 2vw 为周期无限重复。这样,我们就可以省略 background-size 和 background-repeat,代码会更加简洁,同时效果与之前完全一致:
|.tablecloth-repeating { background-image: repeating-linear-gradient(to top, transparent 0 1vw, rgb(0 0 0 / 0.2) 1vw 2vw), repeating-linear-gradient(to right, transparent 0 1vw, rgb(
上面方法对于像桌布这样规则简单的图案非常实用,但如果遇到更复杂的背景需求,问题就变得明显了。举个例子,当你使用了普通(非重复)的渐变作为背景时,图像每次重复衔接的地方往往会出现明显的断层或不连贯。这种不连续会使得背景整体视觉受到影响。
|h1.example { background: linear-gradient(-45deg, black 0, black 25px, yellow 50px) top left / 40px 40px repeat; }
一种方法是精确控制元素和渐变背景的尺寸,同时微调渐变的参数,努力让边缘能够恰好对齐。不过这会比较麻烦。实际上,还有一种更加直接有效的做法:
|.repeating-gradient { background: repeating-linear-gradient(-45deg, black 0 25px, yellow 25px 50px) top left; }
请注意,我们在设置重复渐变时,最后一个颜色停止点通常需要用确切的长度值(比如 50px)明确标明。这一步十分关键,因为这个数值决定了整个渐变模式循环的区间。如果省略了这个长度,浏览器会自动把它当作 100%,即渐变线的终点,这样就无法精确控制重复单位。当你想要渐变平滑过渡时,还需要留意停止点的颜色:最后一个停止点的颜色要与第一个保持一致,否则会在每个循环之间出现突兀的颜色跳变。
举个例子:
|.repeating-smooth { background: repeating-linear-gradient(-45deg, purple 0px, gold 50px); }
这会在 50 像素处产生从紫色到金色的平滑渐变,然后是一个硬切换回紫色,接着是另一个 50 像素的紫色到金色混合。通过添加一个与第一个颜色停止点颜色相同的额外颜色停止点,可以平滑渐变以避免硬停止点线条:
|/* 硬切换 */ .repeating-hard { background: repeating-linear-gradient(-45deg, purple 0px, gold 50px); } /* 平滑过渡 */ .repeating-smooth { background: repeating-linear-gradient(-45deg, purple 0px, gold 50px, purple
你可能已经注意到了,前面的所有重复渐变示例其实都没有为渐变图像指定明确的尺寸。这是因为,默认情况下,渐变图像会自动填充整个元素的背景定位区域,而本身并不具备固定的宽度或高度。
如果你希望改变这种默认行为,可以通过设置 background-size 来控制渐变图像的实际显示尺寸。这样一来,渐变只会按照你设定的尺寸边界进行重复显示。当你同时结合 background-repeat 属性时(默认为 repeat),就会按照给定的大小在背景上平铺多次。不过需要注意的是,这样很容易造成渐变之间产生断档或视觉上的不连续,因为每一个渐变模块会被“切割”后独立重复。
另一方面,在重复线性渐变中使用百分比(比如 color-stop 的位置用 xx% 表达),其计算方式和普通线性渐变一致——都是相对于单个渐变图像尺寸来定位颜色断点。但由于渐变会整体平铺,如果你用百分比,所有断点都会在每一个重复周期中如常展现,背景整体因此并没有真正的“多余重复区域”出现。从效果和实现上,百分比在 repeating-linear-gradient 里的意义往往和原本想要的“无限重复”目标不太相关,因此实际开发较少采用。
虽然线性渐变相当常见,但有时我们会需要更加柔和或中心发散的色彩过渡效果,这时候就可以用径向渐变了。径向渐变能够营造出类似聚光灯、光晕、圆形阴影以及倒影等特殊视觉效果。它的语法和线性渐变接近,不过多了一些参数用来控制形状和渐变范围,这让表现力更灵活:
|radial-gradient( [ [ <shape> ‖ <size> ] [ at <position>]? , | [ <color-stop-list> [, <color-hint>]? ] [, )
简单来说,使用径向渐变时,你可以根据实际需求灵活指定渐变的形状(如圆形或椭圆)、尺寸,以及渐变中心的位置。接下来,只需定义两个或以上的颜色断点,还可以选择性地在中间加入颜色提示点,以便更加精细地控制颜色的过渡区域。其中,形状和大小的组合能创造出丰富的视觉效果。
为了直观理解径向渐变的基础用法,我们先从最基础的示例开始,在不同形状的元素中看看径向渐变的变化效果:
|.radial-simple { background-image: radial-gradient(purple, gold); }
通常情况下,如果没有特别指定径向渐变的中心位置,浏览器会默认将其放在元素的中心点(即 center)。同时,如果没有专门声明形状,默认情况下在非正方形的元素上会生成椭圆形渐变;而当元素本身是正方形时,浏览器会自动渲染为圆形渐变。此外,如果我们没有设置颜色停止点的位置,渐变的计算方式是:第一个颜色自动放在中心点,最后一个颜色分布在最外圈,颜色会在二者之间均匀过渡。
这里有个概念叫“渐变射线”。它与线性渐变中的“渐变线”类似,但它从中心点向外——通常是向右——延伸,整个径向渐变就是根据这条射线来铺展颜色分布的。(稍后我们还会详细解释这个原理。)
径向渐变的图形只存在两种:circle(圆形)和 ellipse(椭圆形)。你可以直接通过关键字明确指定形状,也可以通过设置渐变区域的尺寸参数,实现“变相”地控制形状。
至于尺寸的设定,非常灵活。如果你希望得到一个圆形径向渐变,可以只填写一个非负长度值,代表圆的半径;如果想实现椭圆渐变,则可填写两个非负长度,分别代表椭圆的水平半径和垂直半径。假设你想要如下的径向渐变:
|.radial-circle { background-image: radial-gradient(50px, purple, gold); }
上述写法会生成一个以中心为起点、半径为 50 像素的圆形径向渐变,颜色会从中心的紫色平滑过渡到外圈的金色。如果我们在参数中增加一个数值,就可以分别指定水平和垂直方向的半径——这样渐变区域就会呈现椭圆形。此时,第一个长度控制椭圆的宽度半径,第二个长度则是高度半径:
|.radial-ellipse { background-image: radial-gradient(50px 100px, purple, gold); }
|.circle-grad { background-image: radial-gradient(50px, purple, gold); } .ellipse-grad { background-image: radial-gradient(50px 100px, purple, gold); }
需要特别注意,径向渐变的形状(圆形或椭圆形)不会因为其所在元素的宽高比例而发生变化。也就是说,哪怕圆形渐变在一个长方形区域内,它依然呈现出标准的圆形;而椭圆渐变无论出现在正方形还是长方形区域,始终保持椭圆形状。
在设置径向渐变的尺寸时,除了可以直接用像素等长度单位,还可以对椭圆使用百分比数值。需要强调的是,圆形渐变不支持百分比大小设置,因为百分比涉及到两个轴——长轴和短轴。比如,对于一个宽 500px、高 100px 的区域,如果写 10%,到底指的是 50px 还是 10px?正因为这种二义性,如果给圆形渐变指定百分比值,浏览器会认为无效,从而整个渐变声明失效。
对于椭圆渐变,如果使用百分比来设置大小,通常第一个百分比表示水平方向的半径占整体宽度的比例,第二个百分比则代表垂直方向半径占整体高度的比例。下面的示例展示了用不同设置方式实现的径向渐变效果:
|.percent-ellipse { background-image: radial-gradient(50% 25%, purple, gold); }
当设置椭圆形径向渐变的大小时,可以同时使用百分比和具体长度单位(如像素),分别控制水平方向和垂直方向的半径。例如,你可以让椭圆在水平方向占容器宽度的一定比例(比如 50%),同时把垂直方向的半径固定为 10 像素。这种灵活搭配,能够根据实际需求精准调整椭圆渐变的形状。不过需要注意,混合使用百分比和像素时,实际效果有时会受到容器尺寸影响,出现与预期不同的情况,因此建议预览和检查结果。比如,下面的代码会创建一个水平方向半径为容器 50%,垂直方向半径为 10px 的椭圆径向渐变:
|.mixed-size { background-image: radial-gradient(50% 10px, purple, gold); }
除了可以用具体的长度值(比如像素)或者百分比定义径向渐变的大小,还有四个非常常用的关键字能够简化径向渐变的尺寸控制。通过这些关键字,我们可以更灵活、直观地控制径向渐变扩散到元素空间中的范围。每个关键字的含义及实际效果如下表所示:
这些关键字能够让我们快速实现理想的渐变扩散效果,无论是让颜色只铺满最短距离、整个边缘还是整个角落都很方便。下方实例会用实际图形帮助你对比它们分别用在圆形和椭圆时的不同表现:
|/* 圆形 */ .closest-side-circle { background-image: radial-gradient(closest-side circle, purple, gold); } .farthest-side-circle { background-image: radial-gradient(farthest-side circle, purple, gold); } .closest-corner-circle { background-image: radial-gradient(closest-corner circle
在椭圆形径向渐变中,这些关键字不可以与具体长度值(如像素)或百分比一起混用。例如,写成 closest-side 25px 并不会生效,这样的写法会被浏览器忽略。
你可能已经发现,例子里的径向渐变看起来并不是都以图片的中心为出发点。
如果你希望径向渐变的中心点不是默认的 center,那么可以直接使用任何对 background-position 有效的位置来进行设置。这包括关键字(比如 left、right、top、bottom、center)、像素值、百分比等组合。
“任何有效的位置”包含长度、百分比以及相关关键字,这些都可以随意组合使用。另外,如果你只写了一个位置值,另一个会按照惯例自动补全,例如单独写 center 实际等同于 center center。但需要注意,径向渐变和 background-position 在默认值设置上有区别:径向渐变的默认中心是 center,也就是元素中点,而不是 0% 0%。
下面这组代码示例展示了设置渐变中心位置的不同方式:
|.position-bottom-left { background-image: radial-gradient(at bottom left, purple, gold); } .position-center-right { background-image: radial-gradient(at center right, purple, gold); } .position-pixels { background-image: radial-gradient(at 30
在上述的径向渐变示例中,我们并没有为渐变指定具体的尺寸,因此浏览器默认采用了 farthest-corner 作为大小类型。这个默认值意味着渐变会从指定的中心点扩展,直到触及最远的一个角,把整个区域尽量填满。这种行为很常见,但并不是径向渐变唯一的尺寸选择。实际上,CSS 支持多种渐变尺寸方式。接下来,我们可以尝试为这些渐变手动添加不同的尺寸参数,比较它们在视觉上的区别和变化:
|.sized-1 { background-image: radial-gradient(30px at bottom left, purple, gold); } .sized-2 { background-image: radial-gradient(30px 15px at center right, purple, gold); } .sized-3 {
接下来,我们来看看如果想让径向渐变的颜色变化更丰富,而不仅仅是单纯地从一个颜色平滑过渡到另一个颜色时该怎么做——这时就要用到颜色停靠点了。
径向渐变中的颜色停靠点(color stop)和线性渐变的用法很类似,语法也基本相同。它们都能确定渐变过程中各处显示的具体颜色及其分布。下面我们先回顾一下最基础的径向渐变写法,然后再补充一种更加明确的写法便于理解:
|.radial-simple { background-image: radial-gradient(purple, gold); } .radial-explicit { background-image: radial-gradient(purple 0%, gold 100%); }
径向渐变的颜色过渡是从中心点向四周辐射开的。通常在 0% 的位置(即渐变的中心)会显示起始色,比如紫色;而在 100% 的位置(也就是渐变结束的边缘处)则会变成结束色,如金色。在这两个百分比之间,颜色会平滑过渡,由紫色渐变到金色;而超过 100% 之后,颜色就会保持为纯金色。
如果我们希望让紫色和金色之间有一个第三个过渡色(比如绿色),只需要在这两种颜色之间添加一个新的颜色点即可。如果不给这个新的颜色点指定明确的位置,那么它会默认插入在紫色和金色的正中间,对应的色彩过渡也会变成紫色—绿色—金色。
|.radial-three-colors { background-image: radial-gradient( 100px circle at center, purple 0%, green, gold 100% ); }
如果我们在渐变中明确指定 green 50%,那么绿色就会出现在渐变半径的正中间,这时颜色会按照“紫色 → 绿色 → 金色”的顺序平滑过渡。当渐变射线超过金色指定的位置后,颜色就会持续保持为金色。
这里可以进一步理解一下线性渐变和径向渐变在原理上的不同。线性渐变会在一条渐变线上根据每个颜色停顿点的位置插值颜色,然后将这些颜色值垂直扩展,铺满整个区域。而径向渐变则有些类似,不过它不是扩展成直线,而是从中心向外扩展成一圈一圈的椭圆形图案。每个渐变射线所经过的点,相当于形成一个椭圆,这些椭圆的大小和终点位置相关。你可以参考下方的图表,它展示了什么是渐变射线,以及如何在这些射线上绘制不同尺寸的椭圆。
在了解径向渐变时,我们常常会遇到一个常见疑问:每一条渐变射线的“终点”,也就是 CSS 渐变定义里的 100% 位置,到底是如何确定的?其实,100% 并不是任意指定的点,而是每条射线从中心出发后,与径向渐变最终形状的边界(比如圆或椭圆)的交点。也就是说,射线从中心一直延伸,碰到你设置的外轮廓时,这个交点就成为该射线的 100%。
当我们使用圆形径向渐变时,这一过程更加直观:射线从中心发出,沿直线延伸,直到与半径长度相等的位置碰到圆周,这里就是 100% 终点。例如,如果你设置半径为 25px,那么不论射线指向哪个方向,只要距离中心 25px 就会遇到圆的边界,这正是渐变的终止点。
若渐变形状为椭圆,原理也是类似的,只是多了长轴和短轴的区分。比如 CSS 里写作 40px 20px,表示水平方向半径为 40px,竖直方向半径为 20px。以向右的射线为例,它会从中心点延伸,直到在 40px 处到达椭圆的右侧边界,这里就是这一方向上 100% 的位置。下面的示例代码会具体演示这种椭圆终点的情况:
|.ellipse-endpoint { background-image: radial-gradient(40px 20px ellipse at center, purple, gold); }
线性渐变(linear-gradient)和径向渐变(radial-gradient)在渲染效果上有一个很重要的区别。对于线性渐变来说,颜色的过渡是沿着一条直线依次进行的,这条直线的长度刚好适配整个区域的最长边。换句话说,渐变区域正好被起点(0%)和终点(100%)包裹,区域之外不会显示渐变内容,因此你只能看到渐变线段所覆盖范围内的颜色变化,超出部分不会渲染。
相比之下,径向渐变的控制要灵活得多。我们可以单独设置径向渐变的终点(一般是圆或椭圆边界),让它小于整个背景的宽高。当渐变的最后一个颜色停止点抵达这个终点后,这个颜色会自动向外扩张,把剩余的背景区域全部覆盖。这实际上意味着,终点以外的所有地方都会被最后一个颜色充满。这种现象在前面的图例和例子中已经有所体现。
另外,径向渐变还有一个有趣的小技巧:你可以把某个颜色停顿点(color stop)的位置设置在径向射线的终点“之外”,这会让渐变的颜色突破原本的边界,顺着射线继续延伸,使视觉效果显得更为独特和丰富。简单来说,就是你可以让渐变的颜色不止覆盖本来的半径范围,还可以人为地让它蔓延到更远的位置。下面我们通过一个实际的例子来进一步说明:
|.beyond-endpoint { background-image: radial-gradient( 50px circle at center, purple, green, gold 80px ); }
第一个颜色停止点没有位置,所以它被设置为 0%,也就是中心点。最后一个颜色停止点设置为 80px,所以它将在所有方向上距离中心 80 像素。中间的颜色停止点绿色被放置在两者之间的中点(距离中心 40 像素)。所以我们得到一个渐变,延伸到 80 像素处的金色,然后在该点之后继续金色。即使圆形明确设置为 50 像素大小。它仍然是 50 像素的半径;只是最后一个颜色停止点的位置使这个事实变得模糊无关。在视觉上,我们可能已经声明了这个:
|.visual-equivalent { background-image: radial-gradient(80px circle at center, purple, green, gold); }
换一种说法,我们还可以进一步简化写法:
|.simple { background-image: radial-gradient(80px, purple, green, gold); }
如果你使用百分比来指定颜色停止点的位置,它们的表现方式与前面的像素值示例是一样的。无论使用百分比还是像素,两种写法在视觉效果上是相同的,因此下方的示例也是等效的:
|.equivalent-1 { background-image: radial-gradient(50px, purple, green, gold 160%); } .equivalent-2 { background-image: radial-gradient(80px, purple, green, gold 100%); }
那么,如果我们给某个颜色停止点指定负数的位置又会发生什么呢?实际上,这种情况下的表现和线性渐变里的负颜色停止点类似:负的位置会影响从起点开始的颜色计算,但不会在负区间上显示颜色过渡。所以,这里的渐变在视觉上呈现的效果如下所示:
|.negative-stop { background-image: radial-gradient( 80px, purple -40px, green, gold ); }
在这个例子中,我们设置了几个颜色停止点的位置:第一个“紫色”颜色停止点位于 -40px,而“金色”由于没有明确指定位置,因此自动位于 80px(这也是渐变的终点位置)。中间的“绿色”会被自动安排在这两者正中间的位置。实际效果等同于我们手动为每个颜色停止点都指定一个明确的位置,如下所示:
|.explicit-negative { background-image: radial-gradient(80px, purple -40px, green 20px, gold 80px); }
因此,径向渐变的中心位置的实际颜色是紫色和绿色的混合色,其中包含大约三分之一的紫色和三分之二的绿色。这是因为第一个紫色的停止点被设置在了负数的位置,不会直接出现在可见区域,而绿色则紧接其后。渐变会从这个混合色逐渐过渡到纯绿色,最后延展到终点的金色。至于那些“负空间”里的紫色和绿色的混合区域,由于它们处于径向渐变的可视范围之外,所以在最终效果中实际上不可见。
径向渐变不仅可以自定义其大小和位置,还能设置为极端的参数。这里就引出了一个有趣的问题:如果我们将径向渐变的圆半径设置为零,或者让椭圆的宽度或高度为零,最终的渲染效果会是什么样?其实,这些极端情况在实际开发中完全有可能遇到。除了直接使用 0px 或 0% 指定渐变的大小为零,还可以通过其他方式达到类似的效果:
|.degenerate-case { background-image: radial-gradient(closest-corner circle at top right, purple, gold); }
当我们把径向渐变的大小参数设为 closest-corner,并把中心点移动到元素的右上角时,根据渐变中心到最近一个角的距离,这个距离就会变成 0 像素。那么,这种情况下具体会显示什么效果呢?
按照 CSS 规范,这样设置后,渐变会被当作一个“半径大于 0 的极其微小圆形”来渲染。你可以理解为这个圆的半径非常非常小,可能是十亿分之一像素、一个皮米甚至一个普朗克单位。这种极小的圆虽然理论上还存在,但实际上已经几乎看不到了,也无法渲染出明显的渐变过渡。所以,浏览器通常直接用最后一个颜色停止点的颜色将整个区域填充成纯色,而你几乎感觉不到径向渐变的存在。
如果我们去掉圆的概念,把渐变形状变成椭圆,并且让椭圆的某个尺寸为零,那么它的行为就和上面讲到的会有很大差异。下面我们就来看一下这种情况的具体表现:
|.zero-width-ellipse { background-image: radial-gradient(0px 50% at center, purple, gold); }
按照 CSS 的标准,如果你设置椭圆的宽度为 0,那么浏览器实际绘制出来的效果是:高度会被当作非常大的值,而宽度仅仅比 0 大一点点(几乎可以忽略不计)。这样画出来的“椭圆”,其实看上去和一条通过中心的垂直轴的线很像,所以最终视觉上呈现的就是类似垂直镜像的线性渐变。还有个细节,规范指出此时如果你用百分比来标记颜色停靠点,那么这些百分比都会被处理成 0px,所以整个区域就只会展现最后一个颜色停止点的颜色,也就是一块纯色。
不过,情况会因为你的颜色停靠点是用长度值(比如 px)指定而变化。这种情况下,渐变会呈现为一个对称的水平线性渐变,而且它会沿着垂直方向镜像展开。比如下面这个渐变:
|.zero-width-mirrored { background-image: radial-gradient(0px 50% at center, purple 0px, gold 50px, purple 100px); }
为什么会出现这样的现象呢?我们先来看规范的一个细节:当径向渐变里椭圆的宽度被设置为 0px 时,实际上浏览器会把它当作一个极小的正数来处理,比如我们可以假设成 0.001px(千分之一像素)。假设我们的渐变区域高度是 100 像素,那这个椭圆就相当于宽只有 0.001 像素、高却有 100 像素,也就是宽高比是 1:100,000,极度“扁且瘦”。
进一步地,每当你顺着渐变的射线往外延伸,比如到了 0.5 像素的位置,这时的椭圆宽度变成了 1 像素、高度已经达到 10 万像素;在 1 像素处,椭圆宽 2 像素、高 20 万像素;如果到 5 像素,宽度扩大到 10 像素,高度则有 100 万像素……数字急剧增长。你可以想象这些“椭圆”几乎完全变成了一条狭长的垂直线。
因此,视觉上看起来就像是一条以中心点为镜像轴的水平渐变,但整个过程其实是由一系列极窄极高的椭圆叠加出来的,只不过远远超出了人眼分辨的范围。表现出来的效果,其实和线性渐变中左右镜像(即左右两侧颜色同步扩展)的视觉效果类似,只是这里用的是径向渐变的数学模型,本质上我们已经很难从图像中感受到径向“发散”的属性。
那如果反过来,椭圆的宽度正常但高度设为 0 呢?结果会完全不同。你可能以为会显示一条横向镜像(上下对称)的垂直渐变,但事实不是这样。除去 special case(比如重复渐变),规范要求这种情况下,整个区域会直接被“最后一个颜色停止点”的纯色填充(比如渐变最后设置为 gold,那么所有像素都会被 gold 覆盖)。
简而言之,宽度为零让渐变变成“竖直投影的水平渐变”,高度为零则只会得到一块最后指定的纯色。
|.zero-height-solid-1 { background-image: radial-gradient(50% 0px at center, purple, gold); } .zero-height-solid-2 { background-image: radial-gradient(50% 0px at center, purple 0px, gold 100px); }
为什么会出现这种表现上的差别?其实这和径向渐变的数学构造方式密切相关。我们可以这样理解:按照 CSS 规范,当渐变的某个尺寸被设置为零时,实际上浏览器不会真的取 0,而是会用一个极小但大于零的数来代替。打个比方,如果我们写 0px,浏览器会用类似 0.001px 这样的值来处理;而如果高度设置为 50%,假设最终在页面上是 100 像素,那么宽高比就成了 100 : 0.001,也就是 100,000比1,非常极端的长条形。
那么如果你真要画出一个高为 1 像素的椭圆,理论上宽度要达到 100,000 像素才行。但一般来说,我们渐变的最后一个颜色停靠点,很可能只设置到了 100 像素的位置。这意味着在渐变从紫色过渡到金色的过程中,真正的色彩变化其实全部集中在那 0.001 像素的极窄区域内,其余的空间早已被最后那个颜色(比如金色)完全覆盖,所以你实际只能看到一整片金色。
有些人可能会觉得,如果把颜色停止点(如 gold)的位置带到 100,000px,是否会在界面上看到一条细细的紫色横线?理论上,如果浏览器真按 “0.001px” 处理,是有可能的;但如果浏览器以更小的数值(比如 0.00000001px)来做最小宽度计算,那你就得把数值设置得更大,才能看出变化。实际上,大多数浏览器并不会一层层去渲染这么多极细长的椭圆,而是倾向于在遇到极端参数时直接按照特殊处理逻辑快速输出结果,这样能提升性能和兼容性。如果我们自己实现浏览器,很可能也会采取这种方法。
那如果椭圆的宽和高都设置为零会怎么样?根据规范的描述,这时会采用“零宽度”时的那套处理方式,本质上等价于之前提到的镜像线性渐变现象。
在重复径向渐变中,使用百分比来指定颜色停靠点的位置有时会带来意想不到的效果。比如在重复线性渐变里,如果配合百分比,渐变可能不会形成完整的周期,从而变成非重复的效果。但当我们为径向渐变明确指定圆或椭圆的尺寸,并沿渐变半径用百分比定义颜色停靠点时,特别是在渐变扩散超过第一个周期、能看到“超出射线终点”的区域时,百分比的作用就非常直观了。这样可以很好地控制每一圈或每一段的颜色分布。下面就是一个这样的例子:
|.repeating-radial { background: repeating-radial-gradient( 100px 50px, purple, yellow 20%, purple 40%, yellow 60%, purple 80% ); }
由于设置了五个颜色停止点,并且渐变的尺寸为 100px,所以每隔 20 像素背景颜色就会变化一次,色带会按照你设定的规则不断重复。如果第一个和最后一个颜色停止点选用了同样的颜色,中间的颜色就会平滑过渡,不会出现突兀的分界线。这样得到的效果就是彩色波纹从中心不断扩散,直到覆盖整个背景或渐变区域的边界。
你可以想象,用这种重复的径向渐变,我们能够模拟出类似彩虹一样分明色带、层层扩展的视觉效果:
|.rainbow-radial { background: repeating-radial-gradient( 100px circle at bottom center, rgb(83%,83%,83%) 50%, violet 55%, indigo 60%, blue 65%, green 70%,
在使用重复径向渐变时,有两个关键点需要特别注意:
首先,如果你没有指定径向渐变的尺寸(即没有明确设置其半径或形状),它会自动按元素的宽高比生成一个椭圆形。此时,渐变区域默认会填充整个元素的背景大小,也就是说没声明 background-size 时,渐变会自动适配到背景层的全部宽度和高度(或者在用于列表样式标记等情况下,则依据浏览器给定的默认尺寸来决定)。
其次,径向渐变的默认大小是 farthest-corner,也就是说,渐变的最远射线会自动延伸至元素中心点到背景最远角落的交点,使渐变区域刚好从中心触及到背景边缘的最远处。
需要强调的是,如果直接采用这些默认值去做“重复渐变”,其实并不会看到层层叠加的重复效果。原因在于:背景填满后,只展示了第一次渐变的内容,后续的重复根本不会显示出来。只有在你人为缩小初始渐变的尺寸时,重复部分才会显现,形成周期性的视觉带状或波纹效果。
径向渐变很实用,但如果你想实现一种色彩从中心点沿圆周逐步过渡的效果,比如类似色轮(色相环)那样的分布,就需要用到圆锥渐变。圆锥渐变可以理解为将线性渐变沿一个圆环弯曲,并环绕某个中心点;从每个不同的角度切分出来的圆环边缘,就是线性渐变展开后的样子。 与其用文字解释,不如直接看看代码示例,更直观地理解圆锥渐变在 CSS 中的用法:
|.conic-simple { background: conic-gradient( black, gray, black, white, black, silver ); }
圆锥渐变的颜色变化是围绕圆心按角度逐渐过渡的,你可以理解为每种颜色在特定的角度被分配到了圆周上的某个位置。举个例子,上面代码中灰色分界就在距顶部 60 度的地方出现,而白色的断点刚好位于 180 度。这里有一个关键点:圆锥渐变的起始位置默认在顶部(即 0°),360 度又会回到最初的点,这样最顶端就会出现两个颜色的“交界”,比如黑色与后面紧跟着的灰色。
通常情况下,这种渐变效果的起点(0°)位于正上方,使用的角度标准和 CSS 的 transform 属性等一脉相承。如果你的设计需要将渐变整体顺时针或逆时针旋转,也就是让它从另一个角度开始绘制,只需在 conic-gradient 的参数中用 from 角度 指定起始角度,比如 from 60deg。这样做其实只是让渐变整体转动了指定的角度,每种颜色出现的“顺序”其实不变。你还可以通过不同的角度单位(像 deg、rad、turn 等)来定义这个旋转,效果是等价的,下方有几个例子供参考:
|.conic-rotated-1 { background: conic-gradient(from 144deg, black, gray, black, white); } .conic-rotated-2 { background: conic-gradient(from 2.513274rad, black, gray, black, white); } .conic-rotated-3 {
在设置圆锥渐变时,通过指定不同的起始角度(例如 from 45deg),实际上是在控制整个渐变图案围绕圆心旋转到某个特定位置。这样就能让颜色的分布顺时针整体移动,视觉上类似于把整个色环转了一圈。下面我们通过两个例子来看看不同的起始角度对效果有怎样的影响:
|.conic-no-rotation { background: conic-gradient( black, white 90deg, gray 180deg, black 270deg ); } .conic-with-rotation { background: conic-gradient( from 45deg, black, white 90deg, gray
当我们为渐变设置了 45 度的起始角之后,所有颜色的停靠点都会整体向前顺时针移动 45 度。比如说,本来在 90 度的颜色位置,现在就会出现在 90 度加上 45 度,也就是 135 度的位置。换句话说,原有的各个角度都被一起平移了。
另外,conic-gradient 也允许你自定义渐变的中心点,类似于 radial-gradient 可以改变渐变的起点位置。它们的语法基本相同,下面的代码就给出了几个不同的设置方式:
|.conic-position-1 { background: conic-gradient( from 144deg at 3em 6em, black, gray, black, white ); } .conic-position-2 { background: conic-gradient( from 144deg at 67% 25%
在第一个例子中,圆锥渐变的中心被设置在距离左上角水平方向 3em、垂直方向 6em 的位置。因此,渐变的效果会根据这个新的中心点有所偏移。第二个例子则把渐变的中心放在图像宽度的 67% 与顶部边缘距离 25% 的交点。这种设置方式允许你将渐变中心灵活地放置在容器内的任意位置。至于第三个例子,它展示了当把圆锥渐变的中心移到图像的一条边界(比如底部中央)时的视觉效果:此时渐变图案只显示出一半,我们只能看到某一半的配色分布,例如从 270 度到 90 度之间的部分色彩。
综合来看,圆锥渐变的基本语法结构如下:
|conic-gradient( [ from <angle> ]? [ at <position> ]? , | at <position>, <color-stop>, [ <color-hint> ]?, <color-stop> )
如果你没有特别指定 from 角度,系统会默认为 0deg,即从 0 度位置开始。如果 at 也没有设置,默认则是容器中心点,即 50% 50%。
与径向渐变(radial-gradient)和线性渐变(linear-gradient)类似,圆锥渐变的颜色停止点距离支持用百分比来表示。在这种情况下,百分比会被转化为角度。例如:如果渐变从 0 度开始,写作 25% 就代表 360 度的 25%,也就是 90 度。同样,你也可以直接用角度数(比如 90deg)来指定停止点位置。
需要注意的是,圆锥渐变的颜色停止点只允许用百分比或者角度(deg)表示,不能用长度单位(如 px、em 等);并且你可以灵活混用百分比和角度。
如果你想要圆锥渐变在圆圈周围从颜色到颜色平滑混合,有必要使最后一个颜色停止点与第一个颜色停止点匹配。否则,你会看到前面示例中显示的硬过渡类型。如果你想要创建色相色轮,例如,你需要这样声明它:
|.hue-wheel { background: conic-gradient( red, magenta, blue, aqua, lime, yellow, red ); } .hue-wheel-round { height: 10em; width: 10em; background: conic-gradient( red
这强调了虽然很容易将圆锥渐变视为圆形,但最终结果是矩形,除非有任何裁剪或其他努力使元素的背景区域非矩形。所以如果你考虑使用圆锥渐变来制作,比如饼图,你必须做的不仅仅是定义具有硬停止点的圆锥渐变。
正如我们在线性渐变中使用两个长度百分比值来创建硬停止点一样,我们可以在圆锥渐变中使用两个硬停止点。例如:
|.conic-hard-stops { background: conic-gradient( green 37.5%, yellow 37.5% 62.5%, red 62.5% ); }
在这种语法中,给定的颜色停止点可以写为 <color> <beginning> <ending>,其中 <beginning> 和 <ending> 是百分比或角度值。
如果你想要创建颜色之间更平滑的过渡,但仍然让它们主要是实心的,<color> <beginning> <ending> 语法可以帮助很多。例如,以下圆锥渐变在绿色、黄色和红色之间缓和过渡,而不会使整体渐变过于“模糊”:
|.conic-smooth { background: conic-gradient( green 35%, yellow 40% 60%, red 65% ); }
在这里,渐变的实现方式是,首先从 0 度到 126 度(即占圆周的 35%)呈现一段纯绿色区域。接着,从 126 度到 144 度(也就是 40% 的位置)之间,颜色会逐渐由绿色过渡到黄色。紧接着,从 144 度到 216 度(即 60% 处)是连续的纯黄色区域。类似的过渡也应用在黄色到红色之间,会在 216 度到 234 度(也就是达到 65% 时)平滑混合,最终从 234 度一直到 360 度都是纯红色的扇形区域。
这种写法能够让我们非常灵活且高效地根据百分比或角度来精准控制圆锥渐变的颜色分布。例如,想要仿制前文提到的“野餐桌布”那样的视觉效果,就可以借助这样的渐变语法来实现,既直观又简洁。
|.conic-tablecloth { background-image: conic-gradient( rgba(0 0 0 / 0.2) 0% 25%, rgba(0 0 0 / 0.4) 25% 50%, rgba(0 0 0 / 0.2) 50% 75
这种写法会在渐变背景中巧妙地布置出由四个色块构成的方块图案。通过缩放与重复使用这个渐变图像,能够轻松实现类似格子布的效果。虽然实现方式不如重复线性渐变那样直接且高效,但利用圆锥渐变来达到这样的视觉结果体现了 CSS 渐变用法中的创意和灵活性。
接下来我们可以学习一下重复圆锥渐变。这种方式特别适合快速做出比如放射状的“星爆”图案,或者是环形的棋盘格等复杂但有规律的样式。在实际应用中,只需要简单调整参数,就能实现丰富多样的视觉效果。如下面的例子所示:
|.checkerboard { background: conic-gradient( #0002 0 25%, #FFF2 0 50%, #0002 0 75%, #FFF2 0 100% ); } .checkerboard-repeating { background: repeating-conic-gradient( #343 0 25%
repeating-conic-gradient 用于创建重复的圆锥形渐变图案,非常适合生成棋盘格等重复分布的图案。只需定义一组颜色停止点,渐变会自动以这个序列不断循环填满整个圆——因此通常只需指定两个颜色和它们的角度分布。
通过调整颜色和角度停止点,可以灵活地生成不同尺寸和样式的重复楔形图案。例如:
|.repeating-1 { background: repeating-conic-gradient( #117 5deg, #ABE 15deg, #117 20deg ); } .repeating-2 { background: repeating-conic-gradient( #117 0 5deg, #ABE 0 15deg, #117 0
请注意,第一个(最左侧)示例的渐变过渡非常平滑,这种平滑不仅出现在主区域,在图像顶部同样成立。也就是说,从 350 度的 #117 颜色平滑地过渡到 5 度的 #ABE,这一段和其它渐变区间一样自然衔接。这是重复型圆锥渐变的一大特点:无论从哪里开始,最终都会首尾相连地循环下去,实现真正意义上的闭环渐变。而线性渐变和径向渐变则不会有这样的“环绕”——它们的起点和终点是断开的,这也是为什么在第三个(最右侧)示例中依然可以看到类似的首尾自然融合。
不过,这种环状平滑的特性并不是强制的。比如,看看中间那个例子,能发现 355 度到 360 度这一小段变得非常狭窄,出现了突兀的间断。这种现象的原因在于,出现在渐变函数中的第一个颜色断点是从 0 度延展到 5 度,因此在 355 度之后,没有办法平滑连接回 5 度,最终在 360 度(其实就是 0 度)出现了明显的断层,这就打破了圆锥渐变的闭环特性。
其实从原理上来说,渐变本质上和普通图片没有区别。在 CSS 中,渐变被当作一种可以直接用于背景的图片资源,所以你可以像调整 PNG 或 SVG 那样,灵活运用各种与背景相关的属性,改变渐变的尺寸、摆放位置、平铺方式,甚至叠加到其他背景图层之上。这些操作方法和处理常规图片素材几乎一致,充分体现了渐变的“图像”属性。
比如,假如你需要在网页中呈现有规律的圆点背景,就可以利用径向渐变,并通过设置明确的颜色分界,使其形成类似“硬边界”的效果。这样就能通过简单的渐变定义,并结合 background-repeat,实现基础的圆点图案铺排:
|body { background: radial-gradient( circle at center, rgba(0 0 0 / 0.1), rgba(0 0 0 / 0.1) 10px, transparent 10px, transparent 20px ) center /
实际上,这种渐变背景的视觉效果非常接近于在页面上平铺一个直径为 10 像素、带有大量透明度的深色圆形 PNG 图片。采用 CSS 渐变来实现类似的效果,相比于使用 PNG 图片,具有三个主要优势:
首先,CSS 渐变的样式代码通常比等效的 PNG 图片文件体积要小得多,这有利于优化网页加载速度。其次,直接使用 PNG 图片会造成浏览器额外发起图片资源的请求,影响页面加载效率和服务器性能;而 CSS 渐变属于样式表的一部分,无需额外的网络请求,从而提升了整体表现。最后,调整渐变的参数(如大小、形状或颜色深浅)非常灵活方便,可以随时在 CSS 里进行微调,有助于快速试验和获取理想的视觉效果。
需要注意的是,CSS 渐变虽然非常强大,但它并不能完全替代所有光栅图像或矢量图的用法,有些复杂的效果还是需要外部图片。不过,利用渐变依然可以创造出许多极具表现力的图案或背景。例如,下面的代码就使用渐变实现了特殊的背景效果:
|.curtain-effect { background-image: linear-gradient(0deg, rgba(255 128 128 / 0.25) 0%, rgba(255 128 128 / 0.25) 25%, transparent 75%), linear-gradient(89deg,
这个“窗帘”视觉效果的实现,主要依靠叠加三层线性渐变,并且让它们以不同的横向(x 轴)间隔重复。这样不仅营造出了窗帘的褶皱感,还在背景底部增加了一层“发光”的细腻效果。
最顶层的渐变,其实是从大约 75% 处的半透明浅红色,逐步过渡到完全透明,这往下叠加时为整体增添一种轻柔的色彩过渡感。接下来是两组用于模拟“褶皱”的渐变,把渐变背景看作一组图片的话,这两组图片沿 x 轴平铺,但尺寸不同。一组的背景宽度为 300px、高度 100%,意味着每隔 300px 就会有一个重复的褶皱;另一组设置成每 109px 就重复一次,会产生更多细密、不规则的窗帘纹理。最底层的“发光”效果被设置为“auto”尺寸,能覆盖整个元素,进一步增强层次感。
采用这种叠加多层渐变的方法,非常方便调整每个“折叠”或“发光”区域的重复间隔,只要修改 CSS 里的 background-size 就可以了。而渐变的颜色节点和位置虽然调整略复杂,但只要明确目标色彩,同样可以通过调整相关参数实现。如果需要增加更多的重复“褶皱”,其实就是添加更多渐变层即可,无需改动核心结构。
渐变是一种迷人的图像类型,完全用 CSS 值而不是光栅数据或矢量元素构造。使用三种可用的渐变类型,你可以创建几乎任何图案或视觉效果。线性渐变沿着一条直线向量进行,径向渐变从中心点向外延伸,圆锥渐变围绕中心点包裹。每种类型都有重复和非重复两种变体,你可以通过颜色停止点、颜色提示和位置控制来精确调整它们的行为。
通过将渐变视为图像并利用背景属性(如 background-size、background-position 和 background-repeat),你可以创建从简单的颜色过渡到复杂的装饰图案的一切。渐变提供了出色的性能、无限的可扩展性,以及不需要额外 HTTP 请求的优势,这使得它们成为现代 Web 设计中不可或缺的工具。
创建一个从蓝色到白色的垂直线性渐变。
|.gradient-basic { background-image: linear-gradient(#0066ff, #ffffff); }
创建一个从左到右的线性渐变,从红色过渡到绿色。
|.gradient-right { background-image: linear-gradient(90deg, red, green); } /* 或者使用方向关键字 */ .gradient-right-alt { background-image: linear-gradient(to right, red, green); }
创建一个彩虹渐变,要求每个颜色在渐变中占等分位置。
|.rainbow { background-image: linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet); } /* 或者明确指定位置 */ .rainbow-explicit { background-image: linear-gradient(90deg, red 0%, orange 14.28%
创建一个从紫色到金色的圆形径向渐变。
|.radial-circle { background-image: radial-gradient(circle, purple, gold); }
创建一个椭圆形径向渐变,水平半径为50px,垂直半径为100px,从蓝色过渡到绿色。
|.ellipse-gradient { background-image: radial-gradient(50px 100px, blue, green); }
创建一个圆锥渐变,实现从红色到蓝色的圆形色彩分布。
|.conic-basic { background: conic-gradient(red, blue); }
创建一个重复的条纹图案,交替显示灰色和透明。
|.stripes { background-image: repeating-linear-gradient(90deg, gray 0% 25%, transparent 25% 50%); }
创建一个线性渐变,在25%到75%之间添加一个颜色提示点,使过渡更平滑。
|.gradient-with-hint { background: linear-gradient(to right, rgb(0% 0% 0%) 25%, 50%, /* 颜色提示点 */ rgb(90% 90% 90%) 75%); }
创建一个径向渐变,中心点位于元素左下角,从绿色过渡到黄色。
|.radial-positioned { background-image: radial-gradient(at bottom left, green, yellow); }
创建一个从45度开始的圆锥渐变,从黑色过渡到白色。
|.conic-rotated { background: conic-gradient(from 45deg, black, white); }