入行前端一年多的时间,想提升本身的css技术水平,因而在网上看了些关于css的书籍,想买几本比较好的css书籍啃啃,找来找去,终于找到了《CSS揭秘》这本书。入手这本书后,从开始看到后面,发现书中的不少效果均可以使用渐变来实现,因而,我对渐变产生了兴趣,决定好好掌握css3中的这个属性。结合《CSS揭秘》、张鑫旭大神的深刻理解CSS3 gradient斜向线性渐变和CSS3 radial-gradient径向渐变语法及辅助理解案例10则以及其余的文章,并总结本身的学习过程,因而诞生了这篇关于css3中的渐变文章。javascript
渐变是是以背景图的形式呈如今页面中的,渐变的本质是background-image。在css3中,渐变能够分为线性渐变(linear-gradient)和径向渐变(radial-gradient)。线性渐变是沿着渐变线进行渐变,而径向渐变则是沿着椭圆或者圆形进行四周渐变。css
background-image: linear-gradient( [ <angle> | <side-or-corner> ,]? <color-stop> [, <color-stop>]+ );
[] 在正则表达式中是一个字符类,这里理解为一个小单元便可;html
| 表示或者的意思,要么选择前面,要么选择后面;前端
?表示0个或者1个意思。即若是不指定方向,直接能够直接使用渐变色;java
+加号, 表示1个或者多个。css3
提问:若是angle是45deg,渐变颜色由deepink
到yellow
的渐变,请问下面哪副图是正确的?正则表达式
正确答案:Bchrome
这个理解与咱们所熟知的css3旋转某一个角度有必定的出入,好比,css3中旋转90度的效果是这样的:浏览器
而在线性渐变中,渐变的角度默认是从下到上的垂直方向开始顺时针进行旋转的,咱们能够理解为时钟针旋转的方向,以下图所示:微信
渐变角度指明了线性渐变的方向,0deg表示从上向下渐变;90deg表示从左向右渐变;180deg表示从下向上渐变;270deg表示从右向左渐变;360deg表示从下向上渐变。渐变的角度效果如图所示:
在上面的这个例子中,0deg->360deg的效果其实就是顺时针旋转一圈。
side-or-corner的中文意思是边或者角的意思。在垂直方向的可选值有:top
、center
、bottom
,在水平方向的可选值有left
、center
、right
。默认值为center bottom,即从上向下渐变。能够用to + side-or-corner关键字联合起来使用,若是不加to,则表示渐变的起始点,加上to则表示渐变的方向。例如:to top等价于0deg,to right等价于90deg,to bottom等价于180deg,to left等价于270deg。相关效果以下图所示:
不一样版本浏览器中使用注意:
本文将以W3C标准语法讲解线性渐变linear-gradient
,径向渐变radial-gradient
将在下一篇文章中推出
<color> [ <percentage> | <length> ]
指明线性渐变的颜色、起点、终点。翻译成中文就是:颜色+空格+百分比或者长度值。
background: linear-gradient(#fb3 20%, #58a 80%);
如今顶部20%的区域被填充为#fb3
的实色,底部20%的区域被填充为#58a
的实色,真正渐变的区域在20%到80%高度的区域。若是将两个色标拉近,将两个色标重合在一块儿:
background: linear-gradient(#fb3 50%, #58a 50%);
“若是多个色标具备相同的位置,它们会产生一个无限小的过渡区域,过渡的起止色分别是第一个和最后一个指定值。从效果上看,颜色会在那个位置忽然变化,而不是一个平滑的渐变过程。”
——CSS 图像(第三版)( http://w3.org/TR/css3-images)
由于渐变是一种由代码生成的图像,咱们能像对待其余任何背景图像那样对待它,并且还能够经过background-size 来调整其尺寸:
<div class="box"></div>
.box{ width: 200px; height: 90px; background: linear-gradient(#fb3 50%, #58a 50%); background-size: 100% 30px; }
若是是垂直条纹,代码以及效果以下:
<div class="box"></div>
.box{ width: 210px; height: 90px; background: linear-gradient(to right, #fb3 50%, #58a 50%); background-size: 30px 100%; }
为了不每次改动条纹宽度时都要修改两个数字,咱们能够再次从规范那里找到捷径。
“若是某个色标的位置值比整个列表中在它以前的色标的位置值都要小,则该色标的位置值会被设置为它前面全部色标位置值的最大值。”
——CSS 图像(第三版)( http://w3.org/TR/css3-images)
对于水平和垂直渐变条纹咱们很好理解。若是是斜向渐变,咱们想获得条纹的宽度为15px,咱们能够这样写:
<div class="box"></div>
.box{ width: 200px; height: 100px; background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0); background-size: 30px 30px; }
对比想要的图以及实际效果图,为何获得线条的宽度比咱们想要的线条宽度要小,难道是浏览器出问题了,no,是咱们本身错了。这就须要深刻理解渐变的长度了。
如何肯定渐变线的长度?咱们能够从官网的解释中找到答案:
渐变线是过渐变区域中心的一条直线,而渐变的起点和终点是在与渐变线的垂直线上。若是给定渐变的区域和渐变的方向,咱们就可以肯定渐变的起始点和总长度了。所以在下面的css样式中:
.box{ width: 200px; height: 100px; background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0); background-size: 30px 30px; }
咱们能够用下面的这幅图来计算渐变的长度,咱们指定了区域的大小时30px,根据勾股定理
,能够计算直角三角形的斜边长度。所以,咱们计算获得的条纹的宽度实际是:15/1.414=10.606
,比咱们须要的宽度15p要小。
$$ 15/√2 $$
这就意味着,若是想要让条纹的宽度变化为咱们本来想要的15px,就须要将background-size
指定为2*15*1.4=42.426px
。
咱们来看下修改后的效果,修改background-size
后,获得了咱们想要的效果图。
在上面的例子中,咱们已经使用线性渐变生成了水平和垂直条纹,这里就不在赘述。
在CSS3中,backgrounds支持多背景,越前面的背景越处于上面,也就是背景能够无限累加,而渐变的本质是background-image,因此咱们能够实现任意数量的渐变背景图的叠加效果。
有以下图片:
咱们添加透明值:linear-gradient(to bottom left, #fc3, rgba(255,255,255,0))
.demo{ width: 250px; height: 156px; background: linear-gradient(to bottom left, #fc3, rgba(255,255,255,0)), url(./flower.jpg); }
获得的效果以下:
咱们能够利用这一点,来给背景添加不一样的效果,如让图片不可见(修改成:linear-gradient(to bottom left, #fff, rgba(255,255,255,0))
)。
在实际开发中,若是须要虚线,咱们通常会设置border-style:dashed
,然而这种方法存在一个问题:实线和虚线的比例是必定的。在Chrome和Firefox浏览器下,颜色区的宽高比是3:1
,颜色和透明区的宽度比例是1:1
:
而在IE浏览器下,颜色区的宽高比是2:1
,颜色区和透明区的宽度比例也是2:1
:
若是设计师设计的UI中,要求虚线的颜色区的宽高比是5:3
,实线与虚线的比例是1:1
,此时使用border-style:dashed
就达不到设计师设计的效果了。有两种方法能够解决这个问题:
这里,咱们就可使用linear-gradient
到达设计师想要的效果:
.demo{ height: 3px; background: linear-gradient(to right, #000, #000 5px, transparent 5px, transparent); background-size: 10px 100%; }
对应的效果以下:
考虑下面的场景,咱们须要生成一个对话框:
咱们可能绝大多数使用下面的作法:
.talk { display: inline-block; max-width: 80%; border: 1px solid blue; border-radius: 3px; padding: 6px 10px; font-size: 14px; position: relative; }
.talk:before { content: ''; position: absolute; width: 6px; height: 6px; border: 1px solid blue; border-right: 0; border-bottom: 0; left: -4px; top: 13px; transform: rotate(-45deg); background-color: #fff; }
若是背景不是白色:
.talk { display: inline-block; max-width: 80%; border: 1px solid blue; border-radius: 3px; padding: 6px 10px; background: linear-gradient(to right, deeppink, yellow); font-size: 14px; position: relative; }
能够看到若是背景色不是白色,旋转后的效果就有一个多余的三角形,不是咱们想要的效果,咱们可能尝试这样修改css代码:
.talk:before { content: ''; position: absolute; display: inline-block; width: 0; height: 0; border-top: 5px solid transparent; border-right: 5px solid blue; border-bottom: 5px solid transparent; left: -5.1px; top: 12px; }
额,比上面的效果好多了,可是三角与边框交接的区域多了一个线条,与咱们想要的效果仍是有出入,此时咱们使用线性渐变看看,以下css所示:
.talk:before { content: ""; position: absolute; width: 6px; height: 6px; background: linear-gradient(to top, blue, blue) no-repeat, linear-gradient(to right, blue, blue) no-repeat, linear-gradient(135deg, #fff, #fff 5.2px, hsla(0, 0%, 100%, 0) 5.2px) no-repeat; background-size: 60px 1px, 1px 60px, 60px 60px; transform: rotate(-45deg); left: -4px; top: 13px; }
哇,看起来不错额,今晚能够和妹子约起了。。。
考虑有如下需求:
::before
和::after
伪元素配合实现;<a href="javascript:" class="btn btn-plus" role="button"></a> <a href="javascript:" class="btn btn-minus" role="button"></a>
传统方法:
.btn { display: inline-block; background: #f0f0f0 no-repeat center; border: 1px solid #d0d0d0; width: 24px; height: 24px; border-radius: 2px; color: #666; transition: color .2s; } .btn-plus{ position: relative; } .btn-plus:before{ content: ''; position: absolute; width: 10px; height: 2px; background-color: currentColor; left: 50%; top: 50%; margin-top: -1px; margin-left: -5px; } .btn-plus:after{ content: ''; position: absolute; width: 2px; height: 10px; background-color: currentColor; left: 50%; top: 50%; margin-top: -5px; margin-left: -1px; }
使用线性渐变方法:
.btn { display: inline-block; background: #f0f0f0 no-repeat center; border: 1px solid #d0d0d0; width: 24px; height: 24px; border-radius: 2px; color: #666; transition: color .2s; } .btn-plus { background-image: linear-gradient(to top, currentColor, currentColor), linear-gradient(to top, currentColor, currentColor); background-size: 10px 2px, 2px 10px; } .btn-minus { background-image: linear-gradient(to top, currentColor, currentColor); background-size: 10px 2px; }
这种方法生成加号和等号与传统使用::before
和::after
以及配合background-color
和border
相比,使用渐变背景生成的好处是居中定位方便。
直接看代码:
<div class="clip"></div>
.clip{ width: 150px; height: 150px; background: #58a; background: linear-gradient(135deg, transparent 15px, deeppink 0) top left, linear-gradient(-135deg, transparent 15px, yellow 0) top right, linear-gradient(-45deg, transparent 15px, blue 0) bottom right, linear-gradient(45deg, transparent 15px, green 0) bottom left; background-size: 50% 50%; background-repeat: no-repeat; }
利用线性渐变还能够实现折角效果(计算稍微复杂,详细计算步骤能够看《css揭秘》相关章节),如:
<div class="demo2">重复渐变实现信封效果</div>
.demo2{ width: 300px; font-size: 18px; padding: 10px; border: 10px solid transparent; 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 / 60px 60px; }
<div class="clip">这里是文字</div>
.clip{ padding: 1em; border: 10px solid transparent; background: linear-gradient(white, white) padding-box, repeating-linear-gradient(-45deg, black 0, black 25%, transparent 0, transparent 50%) 0 / 10px 10px; animation: ants 12s linear infinite; max-width: 20em; } @keyframes ants { from { background-position: 0 0; } to { background-position: 100% 100%; } }
在浏览器中的效果以下:
若是将boder
修改成1px solid transparent
,能够看到下面的效果:
更多关于线性渐变的应用能够查看这里
这里的图形都是使用线性渐变实现的,可见CSS3中线性渐变功能之强大!
除了线性渐变linear-gradient
,css3中还支持重复线性渐变reapting-linear-gradient
。
利用重复线性渐变实现斜向条纹的效果,与线性渐变相比,不须要苦苦思考生成一个重复单元,直接改变渐变的角度以及尺寸便可。
background: repeating-linear-gradient(60deg,#fb3, #fb3 15px, #58a 0, #58a 30px);
若是想对提升本身的csss水平,推荐《CSS揭秘》,很不错额。
喜欢的话,就点个赞吧。感谢阅读。
碰见了,不妨关注下个人微信公众号「前端Talkking」