与text-shadow(文字阴影效果)的原理一样,只不过text-shadow是为文字做阴影,而box-shadow是为盒对象做阴影。这里的盒包括块状(block)、内联(inline)、内联块状对象(inline-block)。
如果对盒对象不清楚的童鞋,可以先去学习下什么是盒
一、box-shadow的语法结构
w3c的官方文档,先看一下: CSS3 box-shadow 属性。
box-shadow: h-shadow v-shadow blur spread color inset;
- h-shadow:水平阴影的偏移值,必需,可以为负值。
- v-shadow:纵向阴影的偏移值,必需,可以为负值。
- blur:阴影模糊值,可选,不能为负值。
- spread:阴影的扩展,可选,可以为负值。
- color:阴影的颜色,虽然是可选,但是在不同的浏览器里面解释不一样,有些是黑色,有些是透明,所以建议都要设置。具有透明度的阴影可以用rgba的值。
- inset:内阴影。可选,如果缺省,默认是外阴影(outset)。
至于box-shadow的兼容性,我写的文章几乎不考虑IE,不要怪我任性,因为我只是一个老师,不是一个设计师或者攻城狮,我不需要面对各种客户各种浏览器各种终端,我的地盘我做主!
说人话:老子写文章就是为了高兴,不想让IE破坏了我的兴致。
说实话:我也搞不懂IE各种版本各种乱七八糟的玩意儿@_@
如果你接受我的这个约定,欢迎你继续往下看。
和 text-shaodw一样,所有的阴影都来自于对原对象的复制
二、box-shadow的应用
先设置基础代码如下:
<div class="box">box-shadow</div>
.box{
width:100px;
height:100px;
background-color:rgba(255,204,0,.5);
border-radius:10px;
padding:10px;
margin:10px;
}
再根据需要设置不同的类进行组合。
<div class="box bs1">box-shadow</div>
.bs1{
box-shadow:120px 0px #ccc;}
阴影就是对原对象的复制,包括内边距和边框都属于box的占位范围,阴影也包括对内边距和边框的复制。但是阴影本身不占据布局的空间。
1、四方有一样模糊值的阴影
.bs2{
box-shadow:0 0 20px #666;}
2、有5px扩展的阴影
.bs3{
box-shadow:0 0 0 5px #333;}
阴影不像 border要占据布局的空间,因此要实现对象鼠标经过产生外围的边框,可以使用阴影的扩展来代替 border。
另外一个方法是利用 border的 transparent实现,不过不如 box-shadow的 spread扩展方便,可以看案例思考一下为什么。
如果使用 border,布局会产生影响。
3、拓展为负值的阴影
.bs4{
box-shadow:0 15px 10px -15px #333;
border:none;}
注意:要产生这样的效果,y轴的值和spread的值刚好是一样且相反的。其它边是一样的原理。
4、内阴影
.bs5{
background-color:#1C8426;
box-shadow:0px 0px 20px #fff inset;
}
可以直接为div这样的盒子设置 box-shadow盒阴影,但是不能直接为img图片设置盒阴影。
这样是无效的的:
/* 直接在图片上添加内阴影无效*/
.img-shadow img {
box-shadow: inset 0 0 20px red;
}
可以通过为img的父容器div设置内阴影,然后让img的 z-index为-1,可以解决这个问题。但是这种做法不可以为父容器设置背景颜色,因为父容器的级别比图片高,设置了背景颜色会挡住图片。(我就无意识的犯了这个错,为父父级的容器设置了白色背景,死活看不见图片,搞了半天,还请教了大漠,大漠真的很nice,给我做了个demo,我才发现自己的错误。)
/* 在图片容器上添加内阴影,生效*/
.box-shadow {
box-shadow: inset 0 0 20px red;
}
.box-shadow img {
position: relative;
z-index: -1;
}
当然,如果你非要在父容器上添加背景色,那么加上rgba的半透明背景色也不错。
还有一个更好的方法,不用考虑图片的层级,利用 :before伪元素可以实现,而且还可以为父容器添加背景颜色等。
/*给图片容器上添加伪元素或伪类,不用为img设置负值的z-index值了。有内阴影*/
.pseudo {
position: relative;
background-color:#FC3;
padding:5px;
}
.pseudo:before {
content:'';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
box-shadow: inset 0 0 40px #f00;
}
5、多个阴影
.bs6{
box-shadow:40px 40px rgba(26,202,221,0.5),80px 80px rgba(236,43,120,.5);
border-radius:0;}
此处使用了rgba的颜色值,黄色也是有半透明度的,但是透过黄色看不到下面的青色的阴影,而青色和最下面的粉色阴影却是有透明度的叠加的。
可见,阴影也是有层叠关系的,前面的阴影层级高,会压住后面的阴影。阴影和阴影之间的透明度可见,而主体的box的透明度对阴影不起作用。
在css的标准上有这样一幅图,介绍了 box-shadow的运行原理:
关于这幅图的理解,可以参考大漠的一段话,很透彻:
这张图可以告诉我们很多信息,比如说borer-radius圆角,阴影扩展、阴影模糊以及padding是如何影响对象阴影的:非零值的border-radius将会以相同的作用影响阴影的外形,但border-image不会影响对象阴影的任何外形;对象阴影同box模型的层次一样,外阴影会在对象背景之下,内阴影会在边框之下背景之上。所以整个层级就是:边框>内阴影>背景图片>背景颜色>外阴影。因为大家都知道,我们的背景图片是在背景颜色之上的。
三、drop-shadow和box-shadow的区别
1、模拟投影的效果
比如这种,利用 :after和 :before伪元素来完成投影效果。
2、filter中的drop-shadow
box-shadow是盒阴影,是不会考虑alpha透明度的,所以,如果你的对象是具有透明度的,在 box-shadow和 drop-shadow下就存在很明显的差别。
.box{
width:100px;
height:100px;
border:3px dashed #000000;
border-radius:50px;
margin:20px;
}
.box-shadow{
box-shadow:10px 10px 10px #000;}
.drop-shadow{
filter:drop-shadow(2px 2px 2px #000);}
drop-shadow才是真正的投影。
遗憾的是这个滤镜目前的支持度不够友好,不然用在特殊造型上实在太好了。比如这种气泡框。
可见, box-shadow不支持 :after伪元素做出的造型,而 drop-shadow不仅对透明度支持良好,而且对伪元素的支持也很良好。
.talk{
position:relative;
width:200px;
height:100px;
background-color:#23AE1C;
border-radius:100px/50px;
}
.talk:after{
content:"";
position:absolute;
top:85px;
left:80px;
transform:rotate(30deg);
border-top:30px solid #23AE1C;
border-left:20px solid transparent;
border-right:20px solid transparent;
}
.box-shadow1{
box-shadow:2px 5px 10px #666;}
.drop-shadow1{
filter:drop-shadow(2px 5px 5px rgba(51,51,51,.8));}