CSS的渐变主要分布在 conic-gradient()和repeating-conic-gradient()两个属性。在CSS中,CSS的渐变相当于图像,我们可以使用线性渐变(linear-gradient()和repeating-linear-gradient())、径向渐变(radial-gradient()和repeating-radial-gradient())和锥形渐变(conic-gradient()和repeat-conic-gradient())。事实上这三种渐变就相当于背景图像,而且渐变通常是一种颜色渐变到另一种颜色,但是CSS允许你控制渐变发生的每一个方面,从方向、形状到颜色,以及它们如何从一个渐变到另一个渐变。在这篇文章中,主要和大家一起探讨有关于CSS渐变相关的话题。
CSS 渐变简介
渐变一般指的是从一种颜色平滑地过渡到另一种颜色,而且用户代理(比如浏览器)将其渲染为图像,这个图像可以是背景图像(background-image)、边框图像(border-image)和遮罩图像(mask-image)等,即CSS中可以接受图像的任何属性。开发者可以使用一些指定的 CSS渐变函数来指定这些图像,这样用户代理就要以在渲染页面时自动生成图像。其主要语法:
= [
| |
| |
|
]
比如我们将渐变运用到background-image属性上:
background-image: linear-gradient(#ff8a00, #e52e71);
background-image: repeating-linear-gradient(to right,#ff8a00 10%,#e52e71 20%);}
background-image: radial-gradient(#ff8a00, #e52e71);
background-image: repeating-radial-gradient(circle, #ff8a00 10%, #e52e71 20%);
background-image: conic-gradient(#ff8a00, #e52e71);
background-image: repeating-conic-gradient(#ff8a00 10%, #e52e71 20%);
效果如下:
渐变中的色标
不管使用哪一个渐变函数绘制的渐变图像都由一组指定的颜色构成,并且每个颜色都有对应的位置,在渐变中将其称为,它主要由两部分组成,颜色和渐变线。即渐变函数中指定的 每一个点的颜色。我们通常把这个颜色和相应的位置称为渐变中的色标:
颜色停止()和过渡提示是在一个颜色停止列表()中指定的,这个颜色停止列表是一个包含两个或更多颜色停止和可选过渡提示的列表:
= , [ ? , ]#
= && ?
=
比如下面这个示例:
background-image: linear-gradient(to right, rgb(56, 0, 253) 0%, rgb(255, 0, 146) 20%, rgb(255, 111, 177) 40%, rgb(255, 71, 64) 80%, rgb(30,90,88) 100%);
在这个示例中,渐变的梯度线(也称为“渐变线”)是矩形的左侧边缘至右侧边缘,在这个渐变梯度线上有一个五个颜色组成的颜色停止列表,每个颜色的停止位置分别是0%、20%、40%、80%和100%。颜色的停止位置可以是百分比也可以其他的长度值(),比如px。如果颜色停止位置是百分比,它的计算是根据起始点和结束点之间梯度线的长度来确定,起始点为0%,结束点是100%。梯度线长度从元素的起始点沿终点方向沿梯度线测量。
CSS中的百分比计算是个复杂的体系,假设我们把上面的线性渐变运用于一个宽度为835px的容器中,它的渐变梯度线长度是835px,那么上对应的百分比转换成px的话是用颜色停止位置的百分比值乘以元素的宽度(width):
注意,上面这个示例算是一个特殊的示例,渐变的角度是0(即to right或to left),但渐变的梯度线长度和渐变角度是有关的,比如,我们把to right换成45deg:
background-image: linear-gradient(45deg, rgb(56, 0, 253) 0%, rgb(255, 0, 146) 20%, rgb(255, 111, 177) 40%, rgb(255, 71, 64) 80%, rgb(30,90,88) 100%);
梯度线长度就变了:
这个时候渐变梯度线长度的计算就复杂了。具体如何计算,我们后面会花一定的篇幅来专门介绍。
在渐变中,颜色停止和过渡提示的位置通常位于元素盒子的起始点和结束点之间,但这不是必需的。比如,我们在线上渐变使用多个渐变颜色,但并没有显式指定颜色停止的位置:
background-image: linear-gradient(to right, rgb(56, 0, 253) , rgb(255, 0, 146) , rgb(255, 111, 177) , rgb(255, 71, 64), rgb(30,90,88) );
这个时候会自动被分配一个位置。颜色停止列表中的第一个或最后一个颜色停止分别被指定为渐变梯度线的0%位置(渐变梯度线起始位置)和渐变梯度线的100%位置(渐变梯度线终点位置)。就该示例来说,由五个颜色组成的颜色停止列表,构建四个颜色区间,那么每个区间将会平均分配渐变梯度线的长度,也就是说示例中的第二个颜色的停止位置位于渐变梯度线的25%位置,第三个颜色的停止位置位于渐变梯度线的50%位置,第四个颜色的停止位置位于渐变梯度线的75%位置:
你可能已经发现了,在上面这个示例中,并没有显式的给每个停止颜色指定停止位置,但用户代理在渲染该图像时对每个停止颜色做了一个修正处理。这个过程是一个自动过程,并且这个过程也称为颜色停止修正。用户代理在解析每个色块(停止颜色)的使用位置时,会按下面的步骤来处理:
① 如果第一个停止颜色没有显式设置停止位置,将其停止位置设置为0%;如果最后一个停止颜色没有显式设置停止位置,将其停止位置设置为100%
② 如果一个停止颜色或过渡提示的位置小于停止颜色列表中它前面的任何停止颜色或过渡提示的指定位置,则将其停止位置设置为等于它前面的任何停止颜色或过渡提示的指定位置的最大位置
③ 如果任何停止颜色没有停止位置,那么它们的停止位置会均分有停止位置的前后停止颜色之间的间隔
应用这些规则,所有停止颜色和过渡提示都将有明确的停止位置和停止颜色,并按升序排列。下面这几对渐变,每一对中的后者是前者的手工“修正”版本,通过应用上述规则获得。对于每一对,两个渐变渲染的结果都是相同的。每个箭头中的数字指定在转换中调用了哪些修正步骤。
background-image: linear-gradient(to right, rgb(56, 0, 253) , rgb(255, 0, 146) 20%, rgb(255, 71, 64));
// = ① >>
background-image: linear-gradient(to right, rgb(56, 0, 253) 0% , rgb(255, 0, 146) 20%, rgb(255, 71, 64) 100%);
根据“规则①”对第一个停止颜色和最后一个停止颜色做修正,第一个停止颜色的停止位置位于渐变线的0%,最后一个停止颜色的停止位置位于渐变线的100%:
background-image: linear-gradient(to right, rgb(56, 0, 253) 40% , rgb(255, 0, 146), rgb(255, 71, 64), rgb(188,188,90));
// = ①, ③>>
background-image: linear-gradient(to right, rgb(56, 0, 253) 40% , rgb(255, 0, 146) 60%, rgb(255, 71, 64) 80%, rgb(188,188,90) 100%);
根据“规则①”将最后一个停止颜色(rgb(188, 188, 90))的停止位置修正为渐变线的100%位置,然后根据“规则③”对第二个停止颜色(rgb(255, 0, 146))和第三个停止颜色(rgb(255, 71, 64))的停止位置进行修正。因为这两个停止颜色都没有显式设置停止位置,因此它会均分第一个停止颜色和最后一个停止颜色之间的间距(即渐变线的100% - 40% = 60%),根据计算可以得到第二个停止颜色的停止位置位于渐变线的60%,第三个停止颜色的停止位置位于渐变线的80%:
background-image: linear-gradient(to right, rgb(56, 0, 253) -10% , rgb(255, 0, 146), rgb(255, 71, 64));
// = ①, ③ >>
background-image: linear-gradient(to right, rgb(56, 0, 253) -10% , rgb(255, 0, 146) 45%, rgb(255, 71, 64) 100%);
这个示例也是根据“规则①, ③”来进行修正的,最后一个停止颜色的停止位置会位于渐变线的100%,第二个停止颜色(rgb(255, 0, 146))没有显式设置停止位置,将会均分第一个和最后一个停止颜色位于渐变线上的间距(即100% - (-10%) ÷ 2 = 55%),也就是容器宽度的45%:
background-image: linear-gradient(to right, rgb(56, 0, 253) -50px , rgb(255, 0, 146), rgb(255, 71, 64));
// = ①, ③ >>
background-image: linear-gradient(to right, rgb(56, 0, 253) -50px , rgb(255, 0, 146) calc(50% - 25px), rgb(255, 71, 64) 100%);
这个示例和上面的示例是相似的,不同之处停止颜色的停止位置有两种不同的单位(px和%),但修正规则是相同的,第二个停止颜色rgb(255, 0, 146)没有显式设置停止位置,它会是均分与其相邻两停止颜色位置之间的间距(即100% - (-50px) ÷ 2),最终的值是100% - (-50px) ÷ 2 - 50px = 50% - 25px,在CSS中不同单位之间的混合计算需要使用calc()函数来表达,即calc(50% - 25px):
注意:如果在渐变中停止颜色的停止位置使用混合单位值(比如px,em,vw或 %)时要多加小心,因为这可能会导正停止颜色在之前的停止颜色之前无意地移动。比如background-image: linear-gradient(yellow 100px, blue 50%),当容器高度不小于200px时不会触发任何颜色停止位置的修正,然而,当容器高度是150px时,那么blue的停止位置就相当于75px,位于yellow之前,根据前面“规则②”,blue停止颜色的停止位置会得到修正,会修正为和yellow相同的停止位置,即100px。
background-image: linear-gradient(to right, rgb(56, 0, 253) 20%, rgb(255, 0, 146) 0%, rgb(255, 71, 64) 40%);
// = ② >>
background-image: linear-gradient(to right, rgb(56, 0, 253) 20%, rgb(255, 0, 146) 20%, rgb(255, 71, 64) 40%);
在这个示例中,虽然三个停止颜色都显式指定了停止位置,但第二个停止颜色的停止位置设置了0%,它比前面的停止颜色的停止位置要小,这个时候会根据“规则②”进行调整,会将其停止位置设置为前面最大的位置,即20%:
再来看一个示例:
background-image: linear-gradient(to right, rgb(56, 0, 253), rgb(255, 0, 146) -20%, rgb(32,123,225) 50%,rgb(255, 111, 177) 120%, rgb(55, 71, 164));
// = ①, ② >>
background-image: linear-gradient(to right, rgb(56, 0, 253) 0%, rgb(255, 0, 146) 0%, rgb(32,123,225) 50%,rgb(255, 111, 177) 120%, rgb(55, 71, 164) 120%);
上面我们都是以线性渐变为例向大家阐述了渐变中色标相关的细节,但在径向渐变和锥形渐变中色标的计算有所差异,我们先来看径向渐变为例:
background-image: radial-gradient(50% 100%, #FFFFFF 0%, #972929 34%, #3571DF 67%, #C014CF 100%);
径向渐变和线性渐变的梯度线(渐变线)略有不同,径向渐变的渐变线长度是以其半径,那么对应的百分比也是相对于其半径为基础计算:
如果径向渐变是一个椭圆形渐变:
background-image: radial-gradient(50% 100%, #FFFFFF 50%, #972929 67%, #3571DF 83%, #C014CF 100%);
其停止颜色的百分比也是相对于其半径做计算:
在锥形渐变中,颜色停止就更独特一点,其渐变线是其周长,如果停止颜色的位置是百分比,那么它是相对于360deg来计算的:
background-image: conic-gradient(at 50% 50%, #FFFFFF 0%, #972929 25%, #3571DF 50%, #B60A46 75%, #3DD69F 100%);
第一个停止颜色(#ffffff)位置对应的是0deg,第二个停止颜色(#972929)位置对应的是90deg、第三个颜色(#3571df)对应的是180deg,第四个颜色(#b60a46)对应的是270deg,第四个颜色(#3dd69f)对应的是360deg:
不管是哪种类型的CSS渐变,每个停止颜色都有相应的停止位置,即使未显式设置。当然每种渐变的停止颜色的停止位置计算方式都有所差异。
线性渐变
在Web设计中最为常见的渐变类型是 linear-gradient(),它也常称为“线性渐变”,因为该类型的渐变颜色是从左到右、从上到下、或者在一个方向上行何角度上的渐变。
线性渐变的语法规则如下:
linear-gradient() = linear-gradient([ | to ]? ,)
= [left | right] || [top | bottom]
linear-gradient()函数的第一个参数或 to 是用来指定渐变线方向,并决定停止颜色在渐变线上的停止位置。如果省略该参数,那么它的值是to bottom,即从顶部到底部。该参数接受两种方式指定的值:
:通过角度来指定渐变线的方向,它的单位可以是deg、turn、grads和rad;而且值可以是正负值,其中正值代表顺时针旋转,负值代表逆时针旋转
使用关键字:这里关键字指的是,可以是to top、to right、to bottom、to left、to top right、to bottom right、to bottom left和to top left等。如果参数是to top、to right、to bottom或to left,则渐变线的角度分别是0deg、90deg、180deg或270deg。如果参数指定了方向是某个方框的角度(比如to top left),则渐变线必须具有一定的角度,使其与指定的角相交于同一象限,并且垂直于渐变框的两个相邻角相交的直线。
我们来看一些简单的示例,以双色线性渐变在不同角度和关键词下的效果:
/* CSS */
:root {
--color-start: #09f;
--color-stop: #e52e71;
--linear-direction: to top;
}
div {
width: 100%;
height: 30vh;
border-radius: 5px;
position: relative;
background-image: linear-gradient(
var(--linear-direction),
var(--color-start),
var(--color-stop)
);
}
效果如下:
在渐变中,我们不局限于只有两种颜色!事实上,我们可以有任意多的逗号分隔的渐变色(即),比如下面这个示例,就用了四个渐变颜色:
body {
background-image: linear-gradient(to right, red, #f06d06, rgb(255, 255, 0), green);
}