CSS:linear-gradient 线性渐变

线性渐变 linear-gradient

📚语法定义

CSS3线性渐变的标准写法:

1
background-image: linear-gradient([<angle> | <side-or-corner>,]? <color-stop> [,<color-stop>]+ );

可以看出,线性渐变效果由方向(<angle> | <side-or-corner>可选)及起止色(color-stop至少一对)控制。下面将通过控制变量法,分别对这两者进行分析。

🚥控制渐变方向

要明白渐变方向是怎样控制的,首先要明确三个规定:

  1. 规定 0deg 时方向为
  2. 规定 0deg180deg 是顺时针方向
  3. 默认方向是 180deg, 向下

两个颜色的渐变描述起来是这样的:颜色A 沿着指定方向过渡到 颜色B,例如为两个颜色whiteblack设置渐变方向:

  • to bottom,就是 white 沿着向下方向过渡到 black
  • 45deg,就是 white 沿着 45deg 方向过渡到 颜色B(black)

下面我用不同的方向值替换代码中的 to bottom 来加深理解:

1
background: linear-gradient(to botton,white, black)
关键词 效果 角度 效果
默认
180deg
to bottom
180deg
to top
0deg
to left
-90deg
to right
90deg
to left top
-45deg
to right top
45deg
to left bottom
-135deg
to right bottom
135deg

方向关键词的制订是有一个演变历史的

🚥控制起止颜色 <color-stop>

起止颜色不仅仅是值两个颜色值,还包括颜色的长度。它的赋值语法是:

1
<color|stop> [ <percentage> | <length> ]

如何理解 “颜色的长度” 呢?借用一下张鑫旭前辈一篇博文中的例子:

在一个400*300的 div 上实现一个 (100px, 100px) 到 (200px, 200px) 由红到黄的斜向线性渐变,该如何实现?

线性渐变方向分析图

一图胜千言,根据上图分析的步骤是:

  1. 找出渐变方向:连接两个作用点,角度是135deg
  2. 找默认起止点:沿渐变方向画直线穿过元素中心(xy轴垂线交点),在元素渐变方向的两端,画两条渐变线的垂线,交点即默认起止点
  3. 确定颜色长度:穿过作用点画渐变线垂线,交点与开始点的距离就是长度,求它的值

$$
RedLen = 100*\sqrt{2} = 141
$$

$$
YellowLen = 200*\sqrt{2} = 282
$$

代码:

1
background-image:linear-gradient(135deg,red 141px,yellow 282px);

最终的渲染效果:

最终的渲染效果

下面将沿着从左到右的方向,通过控制颜色数和长度变量,看下各种配置在40*30的元素中如何渲(为了方便表示,r:red,y:yellow,g:green):

两个颜色(yellow,red) 效果 三个颜色(yellow,red,green) 效果 其他 效果
0%,0%
0%,0%,0%
y0%,r100%
0%,50%
0%,50%,100%
y-100%,r100%
0%,100%
25%,0%,100%
y0%,r200%
25%,0%
25%,25%,100%
y-100%,r200%
25%,50%
25%,50%,100%
y20%,r30%,r45%,g55%,g70%,b80%
50%,50%
25%,100%,100%
r30% 45%,g55% 70%,b80%
50%,100%
100%,50%,100%
y25%,r25%,r50%,g50%,g75%,b75%
100%,100%
50%,50%,50%
y25%,r25% 50%,g50% 75%,b75%
100%,0%
100%,100%,100%
- -

由上表总结就是:

  1. 后设颜色长度不能少于前一个颜色长度
  2. 下一个颜色会覆盖前一个颜色
  3. 两个不同颜色间存在距离才能看出渐变效果,否则就是拼接效果
  4. 起止点可以设置超过范围的值
  • 除了设置颜色长度,还可通过设置两个颜色的过渡中心点位置来控制渐变。看看两者的不同:
  1. 设置颜色长度:
1
background-image:linear-gradient(to right, red 0%, yellow 100%);
  1. 设置中心点:
1
background-image:linear-gradient(to right, red, 50%, yellow);
  • 来个复杂的
  1. 默认情况:
1
background-image:linear-gradient(to right, red, yellow, green, blue);
  1. 设置颜色长度:
1
background-image:linear-gradient(to right, red 0%, yellow 33.33%, green 66.66%, blue 100%);
  1. 设置中心点:
1
background-image:linear-gradient(to right, red, 16.67%, yellow, 50%, green, 83.33%, blue);

📚重复渐变语法定义

当渐变效果是重复性的,就可以用另外一个函数 repeating-linear-gradient来渲染。它的语法规则是这样子的:

1
repeating-linear-gradient(  [ <angle> | to <side-or-corner> ,]? <color-stop> [, <color-stop>]+ )

定义时,只需要设置最小精度过渡样式,重复部分交给渲染引擎。另外,为了更好的过渡效果,第一个和最后一个颜色应该相等。下表中会用变量替换指令的 red,yellow,感受下效果:

1
background:repeating-linear-gradient(to right,red,yellow);
变量 效果
red,yellow
r0%,y100%
r,r12.5%,y25%
r,r12.5%,y12.5%,y25%
r,r3px,y7.5%,y15%
r,y6.25%,r12.5%

重复渐变可以做出多规律性的效果:

方向 效果
180deg
135deg

渐变效果是可以叠加的,并且渐变颜色可以选择 transparent

💦兼容性

渐变效果在 没有->提案->各浏览器带前缀实现->标准化->去前缀 过程中有所变迁,不同浏览器是否带前缀和是否带 to 关键词的实现混杂, MDN 最终给出下面跨浏览器兼容实现:

1
2
3
4
5
6
7
.grad { 
background-color: white; /* 不支持渐变的浏览器回退方案 */
background-image: -webkit-linear-gradient(top, black, white); /* 支持 Chrome 25 and Safari 6, iOS 6.1, Android 4.3 */
background-image: -moz-linear-gradient(top,black, white); /* 支持 Firefox (3.6 to 15) */
background-image: -o-linear-gradient(top,black, white); /* 支持旧 Opera (11.1 to 12.0) */
background-image: linear-gradient(to bottom,black, white); /* 标准语法; 需要最新版本 */
}

径向渐变 radial-gradient

📚语法定义

径向渐变(Radial gradients)由其中心点、边缘形状及位置、色值结束点(color stops)定义而成。 与linera-gradient()一样,radial-gradient() 函数也创建一个<image>。它的具体语法如下:

1
2
3
4
5
radial-gradient( [ circle || <length> ] [ at <position> ]? ,
| [ ellipse || [<length> | <percentage> ]{2}] [ at <position> ]? ,
| [ [ circle | ellipse ] || <extent-keyword> ] [ at <position> ]? ,
| at <position> ,
<color-stop> [ , <color-stop> ]+ )

解析:

  • 渐变形状是圆形或椭圆形,默认值为椭圆。若为圆形,可指定一个半径长度(只能是长度值);若为椭圆形,可指定两个对称轴半径长度(可以是长度值或百分比)。
  • <position> 对称中心,如缺省,默认为中心点。
  • <extent-keyword>用于描述边缘轮廓的具体位置,它的关键字及介绍如下:
    关键字 描述
    closest-side 渐变的边缘形状与容器距离渐变中心点最近的一边相切(圆形)或者至少与距离渐变中心点最近的垂直和水平边相切(椭圆)
    closest-corner 渐变的边缘形状与容器距离渐变中心点最近的一个角相交
    farthest-side 与closest-side相反,边缘形状与容器距离渐变中心点最远的一边相切(或最远的垂直和水平边)
    farthest-corner 渐变的边缘形状与容器距离渐变中心点最远的一个角相交
  • <color-stop>包含一个<color>值加上可选的位置值。百分比值0%,或者长度值0,表示渐变中心点;百分比值100%表示渐变射线与边缘形状相交的点。

在一个3em*3em的正方形中,渲染圆形径向渐变。下表将分别控制半径长度及圆心位置,看看不同条件下的渲染效果:

渐变形状 默认半径时中心坐标 效果 默认中心时,半径长度 效果
circle 默认at 50%,50%
0px
circle at 0% 50%
1px
circle at 0% 100%
1em
circle at 50% 0%
1.5em
circle at 100% 0%
3em

在一个3em*3em的正方形中,渲染椭圆径向渐变。下表将分别控制半径长度及对称轴坐标,看看不同条件下的渲染效果:

渐变形状 默认半径时中心坐标 效果 默认中心时,半径长度 效果
ellipse 默认
0px 0px
ellipse at 0% 50%
1em 1em
ellipse at 0% 100%
1em 1.5em
ellipse at 50% 0%
1.5em 1em
ellipse at 100% 0%
3em 0em

在一个4em*3em的正方形中,以(25%,50%)为中心坐标,配合不同的渐变形状,extent-keyword不同表现效果:

extent-keyword 渐变形状 效果 渐变形状 效果
closest-side circle
ellipse
closest-corner circle
ellipse
farthest-side circle
ellipse
farthest-corner circle
ellipse

radial-gradient 的 <color-stop>的定义与 linear-gradient的相同,就不赘述了。

radial-gradient同样支持逗号赋值。下面是利用径向渐变实现的图案:

效果 代码
circle at 50% 50%,white 49%,black 49%,black calc(49% + 1px),white calc(49% + 1px), white
16px at 60px 50%, #000000 0%, #000000 14px, rgba(0, 0, 0, 0.3) 18px, rgba(0, 0, 0, 0) 19px
ellipse farthest-corner at 50% 50%, #00FFFF 0%, rgba(0, 0, 255, 0) 50%, #0000FF 95%
ellipse farthest-corner at 50% 5%, #FFFF80 20%, rgba(204, 153, 153, 0.4) 30%, #E6E6FF 60%
0%