CSS3 gradient介绍

8 Jun

今天出去吃饭,饭后搞活动送了个小礼品。礼品本身不值一提,重要的的是渐变。本篇就介绍并实际做一下这个渐变效果。

gradient0

渐变gradient分为linear-gradient(线性渐变)和radial-gradient(径向渐变)。

线性渐变

W3C标准语法:linear-gradient(angle, color… color); 。第一个参数指明渐变方向,0deg表示渐变从下往上,90deg表示渐变从左往右,180deg表示渐变从上往下,270deg表示渐变从右往左。其实就是顺时针走一圈。你也可以用to  + 关键字,例如to top等于0deg,to right等于90deg,to bottom等于180deg,to left等于270deg。第二参数是起始颜色,中间可以指定多个颜色,依次渐变,最后一个参数是终止颜色。权威请参照W3C

先看简单的,就2个颜色,从白到黑渐变。图1代码linear-gradient(0deg, #fff, #000);linear-gradient(to top, #fff, #000);,代码根据表题依次类推,一图胜千言

gradient1

新版浏览器用W3C的标准语法没问题,但低版本可能尚不支持W3C的标准语法,此时你需要使用各浏览器私有的语法。当然如果你的页面不准备继续支持这些低版本的浏览器的话,此段可以略过。

Webkit引擎(Chrome和Safari),Genko引擎(Firefox),Presto引擎(Opera),Trident引擎(IE)的私有语法和和W3C的标准语法非常像。区别如下:

  1. 需要加上前缀,分别是-webkit-,-moz-,-ms-
  2. -webkit-,-ms-的第一个参数的关键字表示起始位置,因此不需要加to。例如-webkit-linear-gradient(top, #fff, #000);等价于W3C标准语法的linear-gradient(to bottom, #fff, #000);
  3. -moz-的第一个参数的关键字可以可不加to。不加to表示起始位置,加to表示终止位置。例如-moz-linear-gradient(top, #fff, #000);等价于-moz-linear-gradient(to bottom, #fff, #000);
  4. IE10以下是不支持渐变的…因此没有私有语法
  5. Opera从37开始支持,试了下并没有私有语法,加上-o-前缀反而不认…

另外Webkit引擎(Chrome和Safari)的旧版本还支持一种更旧的私有语法,即旧版本的Webkit引擎的浏览器有两种私有语法。旧语法:-webkit-gradient(type, point, point, color, color)。第一个参数type指明linear线性渐变或radial径向渐变。第二三参数分别是渐变的起点坐标和终点坐标。第四五参数是color-stop函数来表示起始和终止颜色。color-stop()支持两个参数,第一个是点的位置,第二个是颜色,例如color-stop(0.5, #fff)表示在渐变范围的中心处有个黑色的过渡色。具体你可以参照这里

为缩减篇幅,下面仍以介绍W3C标准语法为主。

上面的例子是2个颜色渐变,现在试试指定多个颜色间依次渐变。例如linear-gradient(to bottom, yellow, #9C117A, #EF137A, #f00);

gradient2

上面指定了4个颜色,等比例依次渐变,但有时我们需要自己控制渐变的比例,可以在色彩后面追加%百分比。例如linear-gradient(to bottom, yellow 0%, #9C117A 20%, #EF137A 80%, #f00 100%);。第一个颜色渐变范围0-20%,第二个颜色渐变范围20-80%,第三个颜色渐变范围80-100%,第四个颜色渐变范围100-100%渐变,等于第四个颜色没有渐变

gradient3

不在位置范围内的颜色表示不渐变,会填充为实色。例如:

gradient9

background-image:linear-gradient(to bottom, #fb3 20%, #58a 80%);

渐变区域只集中在中间20-80%区域。上部20%是#fb3的实色,下部20%是#58a的实色。即上下各20%的区域都是实色,不渐变。因此如果你将两个颜色的位置值均设为50%,就出现了完全没有渐变效果,全部实色的背景:

gradient10

background-image:linear-gradient(to bottom, #fb3 50%, #58a 50%);

另外,标准规定:如果颜色的位置值比在它之前的所有颜色的位置值都小,那该颜色的位置值会被调整为它前面所有颜色位置值的最大值。因此上面代码可以把第二个色标位置值设为0:

background-image:linear-gradient(to bottom, #fb3 50%, #58a 50%);
//等价于
background-image:linear-gradient(to bottom, #fb3 50%, #58a 0);

用实色这个特点很容易实现常见的条纹状的背景效果:

gradient11

background-image: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);

上面#fb3 25%表示从0-25%区域是实色。#58a 0, #58a 50%等价于#58a 25%, #58a 50%,表示从25-50%区域从#58a渐变至#58a,等于实色。#fb3 0, #fb3 75%等价于#fb3 50%, #fb3 75%,表示从50-75%区域为从#fb3渐变至#fb3,等于实色。最后#58a 0等价于#58a 75%,表示从75%开始全都是实色。

你也可以发挥想象力,将实色这个特点还可用于遮蔽,达到切角效果。这样就避免了多个标签,通过层叠覆盖来实现切角。用渐变简单方便。

gradient

.clip {
    background: #58a;
    background: linear-gradient(135deg, transparent 15px, #58a 0) top left,
                linear-gradient(-135deg, transparent 15px, #58a 0) top right,
                linear-gradient(-45deg, transparent 15px, #58a 0) bottom right,
                linear-gradient(45deg, transparent 15px, #58a 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    padding: .5em .6em;
    color: white;
    font: 50px/64px "微软雅黑";
}

<span class="clip">禮</span>

你也可以将上面线性渐变改成下面介绍的径向渐变来实现弧形切角。

径向渐变

线性渐变是沿着一条直线渐变,而径向渐变是圆形或椭圆形渐变。相比之下稍微复杂一点。

W3C标准语法:radial-gradient(position, shape, size, color-stop);

第一个参数size at position。size指定水平半径和垂直半径。position指明圆心位置,默认值center表示元素中心为渐变的圆心。同样可以指定为top,right,bottom,left,也可以自定义px值或%百分比,对应关系如下。

gradient4

size和position用at连接。例如20px 50px at center,表示以元素中心点为圆心,20px为水平半径,50px为垂直半径的椭圆型渐变。具体效果见下图的第一,二行。

第二个参数size shape。shape可设circle,ellipse。看名字就知道了,前者表示圆形渐变,后者表示椭圆形渐变。

如果shape设成circle,那size的px值就是圆形半径,但不能用%百分比。例如40px circle表示半径为40px的圆型渐变。

如果shape设成ellipse,那size的值分别为椭圆的水平半径和垂直半径。可以用%百分比。例如30% 80% ellipse表示水平半径30%(相对于元素的宽),垂直半径80%(相对于元素的高)的椭圆型渐变。具体效果见下图的第三行。

前两个参数可以合并成size shape at position。例如100px 60px ellipse at right表示圆心在右中位置,水平半径100px,垂直半径60px的椭圆渐变。效果见下图第9单元格。

上面的size除了设px值或%百分比外,还有预定义好的关键字closest-sideclosest-cornerfarthest-sidefarthest-corner(默认值)。看名字也能猜出意思,例如默认值farthest-corner表示渐变半径为从圆心到离圆心最远的角落。效果见下图第4行各单元格。

第四个参数color-stop()函数,在线性渐变里有介绍,不赘述。

效果图如下,表行就是radial-gradient的参数:

gradient5

多色渐变

上面的渐变都只设了两个颜色,一个起始一个终止。其实可以设多个颜色达到多色渐变的效果。例如,左图线性渐变模拟日出效果,右图径向渐变模拟太阳。纯CSS实现,毫无PS痕迹。

gradient6

//左图日出
background-image: linear-gradient(to bottom, #071B26 0%, #071B26 30%, #8A3B12 80%, #240E03 100%);
//右图太阳
background-image: radial-gradient(circle,red,orange,#071B26);

重复渐变

CSS3之前想要对background-image实现重复渐变需要配合background-repeat,但也仅限于重复线性渐变,无法重复径向渐变。CSS3提供了repeating-linear-gradientrepeating-radial-gradient便捷地实现重复渐变。例如

gradient7

//重复线性渐变
background-image: repeating-linear-gradient(red,green 40px, orange 80px);
//重复径向渐变
background-image: repeating-radial-gradient(black 10px,black 20px,#2a2a2a 30px,#2a2a2a 40px);

上面介绍过条纹背景的实现,但现实中的条纹背景,25%的颗粒度实在太大,比如我们想实现每个条纹的宽度为15px,用重复渐变就可以轻松实现:

gradient12

background-image: repeating-linear-gradient(45deg, #fb3, #fb3 15px, #58a 0, #58a 30px);

但通常条纹状背景色可能色差不是那么大,而且如果浏览器不支持repeating-linear-gradient就显示不出背景了。因此一种安全的重复渐变方案是,主色调作为背景,而辅助条纹用渐变:

gradient

background: #58a;
background-image: repeating-linear-gradient(30deg, hsla(0,0%,100%,.1), hsla(0,0%,100%,.1) 15px,
              transparent 0, transparent 30px);

顺着这个思路可以实现信封效果:(关于background两层背景的思路,可以参照这里

gradient13

background: linear-gradient(white, white) padding-box,
	    repeating-linear-gradient(-45deg, red 0, red 12.5%, transparent 0, transparent 25%, 
	              #58a 0, #58a 37.5%, transparent 0, transparent 50%) 0 / 6em 6em;

还有常见的剪裁的效果:

剪裁特效的边框
border: 1px solid transparent;
background: linear-gradient(white, white) padding-box,
	    repeating-linear-gradient(-45deg, black 0, black 25%, transparent 0, transparent 50%) 0 / .6em .6em;
animation: ants 12s linear infinite;	//增加动画效果

@keyframes ants { 
	from { background-position: 0 0; }
	to { background-position: 100% 100%; } 
}

增加动画效果后虚线的边框会不停滑动(关于animation你可以点击这里),单纯将border设成dashed是无法实现滑动效果的。

兼容性

目前gradient在众多浏览器上表现不错,但有些低端浏览器上会出现一些兼容性的问题。我的建议是放弃它们吧,低端浏览器活不过今年。况且渐变毕竟属于渐进增强,即使没有渐变效果也不影响用户的实际使用。

但有时人在江湖身不由己,想象一下和河马们或客户们解释浏览器的占有率,解释渐进增强是件多么累人的事吧。况且你心里很清楚,懂的人不需要解释,不懂的人解释了也没用。所以你可以考虑以下方案模拟出gradient效果:

  1. 最简单的方式就是直接PS出一张图片,虽然多了一次HTTP请求,但你不说谁知道呢^_^
  2. 使用脚本,例如PIE脚本等。但会通过JS对HTML结构进行调整,尤其涉及定位时,bug调试起来真的比较麻烦。
  3. 对低端IE使用滤镜

总结

不忘初心方得始终,来模拟实先一下小礼品的图标(色彩可能做不到完全一致):

gradient8

.priv_icon_coupon {
    width: 70px;
    height: 70px;
    border-radius: 0.3em;
    border:3px solid #fff;
    background-image: linear-gradient(to bottom, #EF137A, #9C117A);
    font: 50px/64px "微软雅黑";
    color: #fff;
    text-align: center;
    text-shadow: 0 1px rgba(0,0,0,.5);
}
<span class="priv_icon_coupon">禮</span>

网上也有很多牛人做的渐变效果,如Lea Verou

Leave a Reply

Your email address will not be published. Required fields are marked *