聊一聊CSS3的渐变——gradient

4,691 阅读9分钟

关于渐变

时下,渐变(gradient)效果在页面设计中已经变得越来越常见了。而且现在的CSS3对于渐变的支持也已经足够的丰富了。虽然我们可能使用过CSS3中的line-gradient属性或radial-gradient属性,但其实CSS3中的渐变功能比我们想象的要强大的多,加以利用会实现很多有趣好玩的东西。本文就来讨论CSS3中的渐变。

taobao首页的按钮和导航栏都使用了css渐变

基础语法

如果你之前使用过CSS3的渐变,对于下面的CSS代码一定有所了解:

<div class="gradient_bg">
</div>

<style>
  .gradient_bg {
    background-image: linear-gradient(gold, #FF837E);
    height: 84px;
    width: 100%;
  }
</style>

他的运行结果如下:

这是一个由上到下、由金色到粉色的渐变色块

linear-gradient()方法的语法看上去还是很清晰的——从某个颜色渐变到另一个颜色。

但是如果要实现下面的几种渐变效果该如何做呢?

这个是由左到右渐变的色块,并且渐变过程只发生在中间一小部分内
这个是由中心向外渐变的色块
这是一个类似“桌布”的div,他也是利用渐变来实现的。。。


我们先来看看linear-gradient的完整语法:

linear-gradient( 
  [ <angle> | to <side-or-corner> ,]? <color-stop> [, <color-stop>]+ )
  \---------------------------------/ \----------------------------/
    Definition of the gradient line        List of color stops  
在CSS语法的说明中,尖括号括起来的部分代表数据类型,如<angle>代表角度数据类型,<image>数据类型。关于更多的数据类型,可以查看MDN的文档

解释一下:

<angle>| to <side-or-corner> 这个在上面的代码示例中并没有使用,它是用来描述渐变发生的方向或角度的。未指定时,默认是由上至下进行渐变。

  • <angle>:代表的是渐变发生的方向或角度。角度向顺时针增加。取值如:45deg、-120deg等等。其中角度是指相对纵坐标而形成的角度。
关于角度单位不仅只有deg,还有grad和turn,比如顺时针旋转90°的话,下面三种是同样 的效果,90deg、100grad、.25turn。再比如顺时针旋转一周的话(360°),下面三种也是同样的效果,360deg、400grad、1turn



此图解释了渐变角度的计算方式
  • <side-or-corner>:直译成中文是“边或角”,也就是说这个值表明了渐变指向哪个边或哪个角。他的取值由一个或两个关键字组成,包括垂直关键字(top和bottom)和水平关键字(left和right),如:to left ;to left top等等。下面是用蓝色向黄色渐变的示例来表示方向值所对应的效果:


  • <color-stop>:由一个<color>值组成,并且跟随着一个可选的终点位置(可以是一个百分比值或者是沿着渐变轴的<length>)。取值如:#FF837E 80%或者 blue 30px。

通过以上对于linear-gradient的解释,让我们重新考虑一下上面提到的色块如何实现。

这个是由左到右渐变的色块,并且渐变过程只发生在中间一小部分内

根据描述,我们可以知道下面的信息:

  • 渐变方向:由左向右(当然你也可以逆向思维,变成由右向左)
  • 渐变位置:渐变是发生在中间的一小部分,我们可以估算为整个区间的20%

所以代码可以写成下面的样子:

div {
  background-image: linear-gradient(to right, gold 40%, #FF837E 60%);
}

至此,我们已经研究的渐变都是基于直线方向上的渐变。然而在实际应用场景中,还有CSS为<gradient>提供的功能都远远超过这个范畴。


实际情况是,CSS渐变可分为三大类:

  1. 线性渐变
  2. 径向渐变
  3. 重复渐变


此图解释了各类渐变的表象

接下来,来说一说其他几类渐变


径向渐变

径向渐变的语法:

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

语法说明看上去很难懂,可以简化一下:

radial-gradient(shape size position, color-stop[...,color-stop]);

从简化后的说明中可以看出,radial-gradient()方法包含两组参数,第一组描述的径向渐变特有的信息,第二组参数与线形渐变一样,描述的是颜色渐变的规则。

  • position:代表径向渐变的圆心位置,语法和线形渐变中的side-or-corner语法很像,同样支持关键字,也支持距离左上角的坐标位置(包括px和百分比单位等)。默认值是中心点。
  • shape:指明径向渐变的形状,可以为circle或者ellipse,从字面意思可知,circle表示圆形,ellipse表示椭圆形。默认为ellipse
  • size:代表径向渐变范围的半径大小,当shape为ellipse时,size需要指定两个值,如:20% 30%;其中第一个值 20%代表相对于元素宽度的20%,而30%代表相对于元素高度的30%。size还可以用一些关键字来进行描述;如下图(知乎怎么插入表格啊?)


图片截至【前端Talkking】@sf
  • color-stop:与线形渐变一致,这里不再赘述。

需要注意的是,当shape取值为circle时,size不能设置为百分数。

举几个例子,来加强记忆。


    .radial_1 {
      /*最简单的渐变:由中心到四周,由蓝色到黄色*/
      background-image: radial-gradient(blue, yellow);
    }
    .radial_2 {
      /*半椭圆形渐变:由左侧中心点到四周,有蓝色到黄色*/
      background-image: radial-gradient(ellipse 100% 50% at left center, blue, yellow);
    }
    .radial_3 {
      /*左上角到右下角的发散式渐变*/
      background-image: radial-gradient(circle farthest-corner at left top, blue, yellow);
    }
    .radial_4 {
      /*指定颜色渐变范围*/
      background-image: radial-gradient(ellipse 50% 30%, blue 30%, yellow 70%);
    }

重复渐变

重复渐变分为两种:线形重复渐变和径向重复渐变。

其中的线形重复渐变——repeating-linear-gradient()的语法如下:

repeating-linear-gradient(  [ <angle> | to <side-or-corner> ,]? <color-stop> [, <color-stop>]+ )
                            \---------------------------------/ \----------------------------/
                              Definition of the gradient line         List of color stops  

径向重复渐变的语法如下:

repeating-radial-gradient( 
       [[ circle  || <length> ]                     [at <position>]? , | 
        [ ellipse || [<length> | <percentage> ]{2}] [at <position>]? , |
        [[ circle | ellipse ] || <extent-keyword> ] [at <position>]? , |
                                                     at <position>   ,    <color-stop> [ , <color-stop> ]+ )
        \---------------------------------------------------------------/\--------------------------------/
                  Contour, size and position of the ending shape               List of color stops  

聪明的你一定发现了,这两个的语法与非重复的语法是一模一样的。本篇不准备着重讲解重复渐变,如果今后有时间会为大家进行详细讲解。

其他知识点

说过了语法,接下来解释一下其他的一些概念。


突然变色

颜色从中间突然发生变化,看上去是两个完整的色块
“如果多个色标具有相同的位置,他们会产生一个无限小的过渡区域,过渡的起止色分别是第一个和最后一个指定值。从效果上看,颜色会在那个位置突然变化,而不是一个平滑的渐变过程。”
——CSS图像(第三版)(w3.org/TR/css3-ima…

要想实现上面的效果,代码可以写成下面的样子:

    div {
      background-image: linear-gradient(to right, blue 50%, yellow 50%);
    }

但是你会发现为了实现这种“突然变色”的效果,每次修改尺寸时你都需要修改两处(上面的两个50%)。不过好在CSS的规范中有下面的规定:

“如果某个色标的位置值比整个列表中在它之前的色标的位置都要小,则该色标的位置会被设置为它前面所有色标位置值的最大值。”
——CSS图像(第三版)(w3.org/TR/css3-ima…

所以,我们可以将第二个色标的位置值设置为0,那么第二个色值的起始位置永远是第一个色值的结束位置。加大了代码的可维护性。

    div {
      background-image: linear-gradient(to right, blue 50%, yellow 0);
    }


<gradient>数据类型

上面我们说的三种渐变都属于CSS数据类型中的<gradient>类型,而<gradient>数据类型又是<image>数据类型的子类型。所以有时能应用到<image>的地方同样也可以应用到<gradient>,比如我们可以利用border-image属性来实现边框的渐变。如下面的效果:


    .border_gradient {
      border: 10px solid transparent;
      border-image: linear-gradient(to right, blue, yellow) 10;
    }

篇幅有限,这里就不对border-image属性进行展开了。


多层级背景

background-image是允许绘制多个背景图像的,他们按照Z轴方向进行堆叠式的摆放,最先指定的图像在最上层。那么基于这个特性,我们可以绘制出很多复杂好玩的效果出来,最先想到的就是网格效果

上面提到的桌布效果
    .grid {
      background-color: white;
      background-image: linear-gradient(90deg, rgba(200, 0, 0, .5) 50%, transparent 0),
                        linear-gradient(rgba(200, 0, 0, .5) 50%, transparent 0);
      /*这里使用rgba,使颜色的透明度为50%*/
      background-size: 50px 50px;
    }

其实“桌布效果”是由横竖两个线形渐变混合,再加上background-color形成的。


上面为横向渐变,下面为纵向了渐变


更多好玩的渐变

下面推荐两个利用CSS渐变实现的网站,上面有各种有趣好玩的实践例子。



谢谢支持:

如果您觉得这篇文章对于您有帮助,请关注微信公众号——“较真的前端”。

这里有更多更好玩的前端知识分享。

参考文章: