CSS魔法堂:Bo-Shadow没那么简单啦:)
前言
说起box-shadow那第一个想法当然就是用来实现阴影,其实它还能用于实现其他好玩的效果的,本篇就打算说说box-shadow的那些事。
二话不说看效果
3D小球
.ball{ background: rgba(100,100,100,0.2); width: 100px; height: 100px; padding: 10px; border-radius: 50%; box-shadow: -14px 8px 100px # 333 inset, 0 0 2px # 888, 3px -1px 4px # 444;}
纸张阴影(来自@张鑫旭老师)
.curved_box { display: inline-block; *display: inline; width: 200px; height: 248px; margin: 20px; background-color: # fff; border: 1px solid # eee; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 60px rgba(0, 0, 0, 0.06) inset; -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset; position: relative; *zoom: 1;}.curved_box:before { -webkit-transform: skew(-15deg) rotate(-6deg); -moz-transform: skew(-15deg) rotate(-6deg); transform: skew(-15deg) rotate(-6deg); left: 15px;}.curved_box:after { -webkit-transform: skew(15deg) rotate(6deg); -moz-transform: skew(15deg) rotate(6deg); transform: skew(15deg) rotate(6deg); right: 15px;}.curved_box:before, .curved_box:after { width: 70%; height: 55%; content: ' '; -webkit-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); position: absolute; bottom: 10px; z-index: -1; }
细读属性
看到上面这么绚丽的效果,是不是迫不及待想弄清box-shadow呢?下面我们来一步步解密它吧!
概述属性语法
box-shadow: none | [,]*
默认值为none
:`inset? && {2,4} && ?` shadow pattern ,默认为outset,即采用outer box-shadow。通过设置为inset时,则采用inner box-shadow。 horizontal offset ,阴影距离原位置的水平位移,正数表示向右移动,负数表示向左移动。 vertical offset ,阴影距离原位置的垂直位移,正数表示向下移动,负数表示向上移动。 blur radius ,默认值为0,阴影模糊度半径。 spread distance ,默认值为0,扩展或缩小阴影的作用面积。
,阴影颜色,默认与color
属性一致。
注意:我们可以同时设置多个阴影,而阴影的z-index值从左向右递减。
outer box-shadow 和 inner box-shadow怎么玩?
默认情况下采用的是outer box-shadow,当在box-shadow
中添加inset关键词后,则采用inner box-shadow了,但到底它俩的效果是如何的呢?
.box{ float: left; background: # 888; width: 100px; height: 100px; margin-right: 20px;}.outer-box-shadow{ box-shadow: 10px 10px # F00;}.inner-box-shadow{ box-shadow: 10px 10px # F00 inset;}
outer-box-shadow
特点:阴影落在元素的border box之外。
实现原理:
创建一个与元素border box尺寸一致的阴影盒子;
将阴影盒子定位到于元素border box重合,并位于元素之下;
根据
spread distance
缩放阴影盒子的尺寸;根据
horizontal offset
和vertical offset
来相对原位置作移动;根据
blur radius
对阴影盒子作加工;最后将阴影盒子与元素border box重合部分剪切掉。
.box{
background: # 888;
width: 100px;
height: 100px;
}
.outer-box-shadow{
box-shadow: 90px 10px # F00;
}
模拟一下:![UI设计](https://v1cdn.imspm.com/2016051109012825.png)
.box{
position: relative;
}
.box-shadow{
position: absolute;
z-index: -1;
background: # F00;
width: 100px;
height: 100px;
left: 20px;
top: 20px;
}
.box-content{
background: # 888;
width: 100px;
height: 100px;
}
inner-box-shadow 特点:阴影落在元素的padding box之内。实现原理(纯个人理解):1. 创建一个与元素padding box尺寸一致的阴影盒子;2. 将阴影盒子定位到于元素padding box重合,并位于元素之上;3. 水平和垂直各画两条线,分别跟元素padding edge重合;(共4条分别记为left/top/right/bottom-guideline)4. 根据`spread distance`移动4条线。spread distance为正数时,left-guideline向右移动,top-guideline向下移动,right-guideline向左移动和bottom-guidelien向上移动;spread distance为负数时,则相反。5. 根据`horizontal offset`和`vertical offset`移动left/top/right/bottom-guideline。6. 根据`blur radius`加工元素各padding edge至其对应的guideline间的区域.7. 对阴影盒子进行剪裁 1. 剪切掉不与元素padding box重叠的部分; 2. 仅显示元素各padding edge至其对应的guideline间的区域。![UI设计](https://v1cdn.imspm.com/2016051109012826.png)
.box{
float: left;
background: # 888;
width: 100px;
height: 100px;
margin-right: 10px;
}
.box1{
box-shadow: 0 0 0 20px red inset;
}
.box2{
box-shadow: 10px 0 0 20px red inset;
}
.box3{
box-shadow: 10px 0 10px 20px red inset;
}
.box4{
box-shadow: 0 0 10px 50px red inset;
}
模拟一下:![UI设计](https://v1cdn.imspm.com/2016051109012827.png)
.box-shadow{
position: relative;
display: inline-block;
background: red;
overflow: hidden;
}
.bg{
position: absolute;
background: # 888;
left: 30px;
right: 10px;
top: 20px;
bottom: 20px;
}
.content{
position: relative;
z-index: 1;
width: 80px;
height: 80px;
padding: 20px;
}
### 模糊边框 by `blur radius` W3C spec中没有规定浏览器厂商使用哪种方式实现模糊效果,反正效果与高斯模糊效果差不多就是了。但有一点我们需要注意的,那就是 模糊效果会扩大阴影的面积 。![UI设计](https://v1cdn.imspm.com/2016051109012828.png)
.outline{
border: 1px solid red;
margin: 40px 0;
}
.s{
background: rgba(255, 100, 100, 0.1);
width: 100px;
height: 100px;
}
.s1{
box-shadow: 110px 0 0 # 333;
}
.s2{
box-shadow: 110px 0 20px # 333;
}
.s3{
box-shadow: 110px 0 40px # 333;
}
sample1
sample2
sample3
sample1是`blur radius`为0的效果,可以看到阴影尺寸与元素尺寸一模一样。而sample2是`blur radius`为20px的效果,可以看到阴影尺寸有所扩展了,而sample3则扩展得更多一些。 现在我们感性上认知到`blur radius`值大于0时会扩展阴影尺寸,那么到底扩展多少呢?那我们要先明确模糊发生的起始位置了。1. 对于outer-shadow-box而言,模糊发生的起始位置就是阴影盒子的各边;2. 对于inner-shadow-box而言,模糊发生的起始位置就是各guideline。 然后模糊效果是从发生的位置,对于水平方向的边或guideline则向垂直方向发散,对于垂直方向的边或guideline则向水平方向发散,且发散的距离相同。 发散的距离相同,因此每个方向各发散为 `blur radius/2` 的距离。看sample3中阴影尺寸已经与元素盒子重叠了,因为阴影盒子左边框向左发散了20px了,超过它俩之间10px的水平距离了,而sample2则恰恰邻近而已。### 缩放阴影尺寸 by `spread distance` 如果说`blur radius`是暗地里扩大阴影的尺寸,那么`spread distance`则是明目张胆地缩放阴影的尺寸了。![UI设计](https://v1cdn.imspm.com/2016051109012829.png)
.outline{
border: 1px solid red;
margin: 40px 0;
}
.s{
background: rgba(255, 100, 100, 0.1);
width: 100px;
height: 100px;
}
.s1{
box-shadow: 110px 0 0 # 333;
}
.s2{
box-shadow: 110px 0 0 10px # 333;
}
.s3{
box-shadow: 110px 0 0 -10px # 333;
}
sample1
sample2
sample3
还记得[《CSS魔法堂:重拾Border之——解构Border》](http://www.cnblogs.com/fsjohnhuang/p/5436087.html)中提及通过`border-top/right/bottom/left-colors`实现彩虹边框吗?由于兼容性问题和1px对应一种color的缘故,实际应用得很少,但通过outer-box-shadow和`spread distance`我们就可以得到效果更好,兼容性很高的实现方案了。![UI设计](https://v1cdn.imspm.com/2016051109012830.png)
.rainbow{
margin: 50px;
width: 100px;
height: 100px;
box-shadow: 0 0 0 2px rgb(255,0,0),
0 0 0 5px rgb(255,165,0),
0 0 0 8px rgb(255,255,0),
0 0 0 10px rgb(0,255,0),
0 0 0 12px rgb(0,127,255),
0 0 0 15px rgb(0,0,255),
0 0 0 20px rgb(139,0,255);
}
### 弄清各图层的z-index![UI设计](https://v1cdn.imspm.com/2016051109012831.jpg) 上图可以看到没有阴影时,各图层的z-index顺序。那么阴影呢?1. 对于outer-box-shadow,则其z-index高于margin图层,低于background-color图层;2. 对于inner-box-shadow,则其z-index高于padding图层,低于content图层。### 阴影的position 通过`horizontal/vertical offset`重定位阴影盒子,通过`blur radius`或`spread distance`缩放阴影盒子的尺寸,但请注意的是 阴影盒子不影响其他盒子的布局 ,其实阴影盒子就相当于采用absolute定位一样,不会占据Normal flow的空间,也不会影响其他元素的布局,因此仅修改阴影位置或尺寸时,只会触发repaint,而不会触发reflow。## 圆角or直角box-shadow傻傻分不清楚? 阴影不仅默认尺寸与元素盒子一致,默认形状也一致。也就是元素盒子采用圆角时,阴影的默认形状也是圆角的。既然说是默认形状一致,就是说可以不一致咯!那到底如何不一致呢,下面我们一起来看个究竟吧!![UI设计](https://v1cdn.imspm.com/2016051109012832.png)
.s1{
background: # 0EF;
width: 100px;
height: 100px;
border-radius: 10px;
box-shadow: 110px 0 0 -10px # 333,
220px 0 0 0 # 666,
360px 0 0 20px # 888;
}
sample1
当设置`spread distance`后,border-radius的值也将随之变化,具体公式为`border-radius + spread-distance * (1 + (border-radius / spread-distance - 1)^3)`。因此`spread distance`为正数时,border-radius会变大; 而`spread distance`为负数时,border-radius会减小,直至为0px为止。## 被割裂的box-shadow 当设置box-shadow的盒子被拆分为多个盒子时,其对应的box-shadow又会如何呢?其实这不仅仅是box-shadow的问题,如border、background-image等均会遇到同样的问题。CSS3中引入一个新特性`box-decoration-break`来设置上述情况时的渲染效果。`box-decoration-break: slice | clone` slice 是默认值,表示首先按未拆分时的状态渲染border、background-image等样式,然后再将其直接拆分为多个盒子; clone 表示首先将其直接拆分为多个盒子,然后再逐个盒子渲染border、background-image等样式。![UI设计](https://v1cdn.imspm.com/2016051109012833.png)
.intro{
font-size: 14px;
line-height: 1.5;
text-indent: 1em;
width: 300px;
}
.intro span{
border: 1px solid # 666;
border-radius: 5px;
box-shadow: 5px 3px 3px # AAA;
}
.slice{
-webkit-box-decoration-break: slice;
}
.clone{
-webkit-box-decoration-break: clone;
}
Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.
Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.
从上面可以看到,与其说`box-decoration-break`的属性值影响`box-shadow`的效果,还不如说是`box-decoration-break`的属性值影响`border-radius`和`border`作用到元素盒子的效果,然后由盒子的效果再间接影响`box-shadow`的效果。 兼容性 ![UI设计](https://v1cdn.imspm.com/2016051109012834.png)IE和Edge均不支持,FF支持得最好,而Webkit内核的则要加-webkit-前缀。 对于不支持的浏览器,其效果如同`box-decoration-break:slice` ## 兼容性![UI设计](https://v1cdn.imspm.com/2016051109012835.png)IE9都支持`box-shadow`多让人可喜可贺的消息啊(因为我工作中只需兼容IE9+就Ok了:))。但IE6~8呢?方案很多啦,上面也有简单的介绍到。@张鑫旭老师提到在模拟blur radius效果时,采用以下方案
.ieBlock{
height:100px;
width:100px;
background:# 000;
filter:progid:DXImageTransform.Microsoft.Blur(pixelradius=10);
-ms-filter:"progid:DXImageTransform.Microsoft.Blur(pixelradius=10)";
}
要比采用以下方案要好!
.shadow {
-moz-box-shadow: 3px 3px 4px # 000;
-webkit-box-shadow: 3px 3px 4px # 000;
box-shadow: 3px 3px 4px # 000;
/ For IE 8 /
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='# 000000')";
/ For IE 5.5 - 7 /
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='# 000000');
}
另外若想不假思索地用到生产环境中,还是用成熟的CSS库较好。具体请参考[PIE使IE支持CSS3圆角盒阴影与渐变渲染](http://www.zhangxinxu.com/wordpress/2010/07/pie%E4%BD%BFie%E6%94%AF%E6%8C%81css3%E5%9C%86%E8%A7%92%E7%9B%92%E9%98%B4%E5%BD%B1%E4%B8%8E%E6%B8%90%E5%8F%98%E6%B8%B2%E6%9F%93/)## 总结 尊重原创,转载请注明来自:[http://www.cnblogs.com/fsjohnhuang/p/5477194.html^_^](http://www.cnblogs.com/fsjohnhuang/p/5477194.html%5E_%5E)肥仔John## 感谢[the-box-shadow](https://www.w3.org/TR/css3-background/)[break-decoration](https://www.w3.org/TR/2014/WD-css3-break-20140116/)[CSS3 box-shadow实现纸张的曲线投影效果](http://www.zhangxinxu.com/wordpress/2010/12/css3-box-shadow%E5%AE%9E%E7%8E%B0%E7%BA%B8%E5%BC%A0%E7%9A%84%E6%9B%B2%E7%BA%BF%E6%8A%95%E5%BD%B1%E6%95%88%E6%9E%9C/)[CSS实现跨浏览器兼容性的盒阴影效果](http://www.zhangxinxu.com/wordpress/2010/04/css%E5%AE%9E%E7%8E%B0%E8%B7%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E5%85%BC%E5%AE%B9%E6%80%A7%E7%9A%84%E7%9B%92%E9%98%B4%E5%BD%B1%E6%95%88%E6%9E%9C/)[CSS实现跨浏览器的box-shadow盒阴影效果(2)](http://www.zhangxinxu.com/wordpress/2010/07/css%E5%AE%9E%E7%8E%B0%E8%B7%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84box-shadow%E7%9B%92%E9%98%B4%E5%BD%B1%E6%95%88%E6%9E%9C2/)[PIE使IE支持CSS3圆角盒阴影与渐变渲染](http://www.zhangxinxu.com/wordpress/2010/07/pie%E4%BD%BFie%E6%94%AF%E6%8C%81css3%E5%9C%86%E8%A7%92%E7%9B%92%E9%98%B4%E5%BD%B1%E4%B8%8E%E6%B8%90%E5%8F%98%E6%B8%B2%E6%9F%93/)《图解CSS3核心技术与案例实战》 —— 3.5 CSS3盒子阴影属性关键字:css
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!