今天出去吃饭,饭后搞活动送了个小礼品。礼品本身不值一提,重要的的是渐变。本篇就介绍并实际做一下这个渐变效果。
线性渐变
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);
,代码根据表题依次类推,一图胜千言
新版浏览器用W3C的标准语法没问题,但低版本可能尚不支持W3C的标准语法,此时你需要使用各浏览器私有的语法。当然如果你的页面不准备继续支持这些低版本的浏览器的话,此段可以略过。
Webkit引擎(Chrome和Safari),Genko引擎(Firefox),Presto引擎(Opera),Trident引擎(IE)的私有语法和和W3C的标准语法非常像。区别如下:
- 需要加上前缀,分别是-webkit-,-moz-,-ms-
- -webkit-,-ms-的第一个参数的关键字表示起始位置,因此不需要加to。例如-webkit-linear-gradient(top, #fff, #000);等价于W3C标准语法的linear-gradient(to bottom, #fff, #000);
- -moz-的第一个参数的关键字可以可不加to。不加to表示起始位置,加to表示终止位置。例如-moz-linear-gradient(top, #fff, #000);等价于-moz-linear-gradient(to bottom, #fff, #000);
- IE10以下是不支持渐变的…因此没有私有语法
- 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);
linear-gradient(to bottom, yellow 0%, #9C117A 20%, #EF137A 80%, #f00 100%);
。第一个颜色渐变范围0-20%,第二个颜色渐变范围20-80%,第三个颜色渐变范围80-100%,第四个颜色渐变范围100-100%渐变,等于第四个颜色没有渐变
不在位置范围内的颜色表示不渐变,会填充为实色。例如:
background-image:linear-gradient(to bottom, #fb3 20%, #58a 80%);
渐变区域只集中在中间20-80%区域。上部20%是#fb3的实色,下部20%是#58a的实色。即上下各20%的区域都是实色,不渐变。因此如果你将两个颜色的位置值均设为50%,就出现了完全没有渐变效果,全部实色的背景:
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);
用实色这个特点很容易实现常见的条纹状的背景效果:
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%开始全都是实色。
你也可以发挥想象力,将实色这个特点还可用于遮蔽,达到切角效果。这样就避免了多个标签,通过层叠覆盖来实现切角。用渐变简单方便。
.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值或%百分比,对应关系如下。
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-side
,closest-corner
,farthest-side
,farthest-corner
(默认值)。看名字也能猜出意思,例如默认值farthest-corner表示渐变半径为从圆心到离圆心最远的角落。效果见下图第4行各单元格。
第四个参数color-stop()函数,在线性渐变里有介绍,不赘述。
效果图如下,表行就是radial-gradient的参数:
多色渐变
上面的渐变都只设了两个颜色,一个起始一个终止。其实可以设多个颜色达到多色渐变的效果。例如,左图线性渐变模拟日出效果,右图径向渐变模拟太阳。纯CSS实现,毫无PS痕迹。
//左图日出
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-gradient
和repeating-radial-gradient
便捷地实现重复渐变。例如
//重复线性渐变
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,用重复渐变就可以轻松实现:
background-image: repeating-linear-gradient(45deg, #fb3, #fb3 15px, #58a 0, #58a 30px);
但通常条纹状背景色可能色差不是那么大,而且如果浏览器不支持repeating-linear-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两层背景的思路,可以参照这里)
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效果:
- 最简单的方式就是直接PS出一张图片,虽然多了一次HTTP请求,但你不说谁知道呢_
- 使用脚本,例如PIE脚本等。但会通过JS对HTML结构进行调整,尤其涉及定位时,bug调试起来真的比较麻烦。
- 对低端IE使用滤镜
总结
不忘初心方得始终,来模拟实先一下小礼品的图标(色彩可能做不到完全一致):
.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