3.5 CSS3盒子阴影属性
box-shadow也是CSS3新增的一个重要属性,用来定义元素的盒子阴影。本节主要介绍CSS3的box-shadow的属性以及如何使用。
3.5.1 box-shadow属性的语法及参数
在具体学习box-shadow使用方法之前,我们必须先知道box-shadow使用的语法规则。
box-shadow:none | [ <length> <length> <length>?<length>? || <color> ] [ , <length> <length> <length>? <length>?|| <color> ]+
上面的语法规则可以简写如下:
box-shadow:none | [inset x-offset y-offset blur-radius spread-radius color], [inset x-offset y-offset blur-radius spread-radius color]
box-shadow属性可以使用一个或多个投影,如果使用多个投影时必须使用逗号“,”隔开。
其实box-shadow属性很简单,可以为其设置以下参数。
none:默认值,元素没有任何阴影效果。
inset:阴影类型,可选值。如果不设置,其默认的投影方式是外阴影;如果取其唯一值“inset”,就是给元素设置内阴影。
x-offset:阴影水平偏移量,其值可以是正负值。如果取正值,则阴影在元素的右边,反之取负值,阴影在元素的左边。
y-offset:阴影垂直偏移量,其值可以是正负值。如果取正值,则阴影在元素的底部,反之取负值,阴影在元素的顶部。
blur-radius:阴影模糊半径,可选参数。其值只能是正值,如果取值为“0”时,表示阴影不具有模糊效果,如果取值越大,阴影的边缘就越模糊。
spread-radius:阴影扩展半径,可选参数。其值可以是正负值,如果取值为正值,则整个阴影都延展扩大,反之取值为负值,则整个阴影都缩小。
color:阴影颜色,可选参数,如果不设定任何颜色时,浏览器会取默认色,但各浏览器默认色不一样,特别是在Webkit内核下的浏览器将无色,也就是透明,建议不要省略这个参数。
3.5.2 box-shadow属性使用方法
和PSD软件制作图片相比,box-shadow修改元素的阴影效果要方便得多,因为box-shadow可以修改六个参数,得到不同的效果。下面结合一些简单的案例来对box-shadow属性进行演示说明。
1.单边阴影效果
定义元素的单边阴影效果和调协border的单边边框颜色是相似的,例如:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>box-shadow设置单边阴影效果</title>
<style type="text/css">
.box-shadow {
width: 200px;
height: 100px;
border-radius: 5px;
border: 1px solid #ccc;
margin: 20px;
}
.top {
box-shadow: 0 -2px 0 red;
}
.right {
box-shadow: 2px 0 0 green;
}
.bottom {
box-shadow: 0 2px 0 blue;
}
.left {
box-shadow: -2px 0 0 orange;
}
</style>
</head>
<body>
<div class="box-shadow top"></div>
<div class="box-shadow right"></div>
<div class="box-shadow bottom"></div>
<div class="box-shadow left"></div>
</body>
</html>
效果如图3-38所示。
这个案例中,使用box-shadow给元素设置了顶边、右边、底边和左边的单边阴影效果。主要通过box-shadow的水平和垂直阴影的偏移量来实现,其中x-offset为正值时,生成右边阴影,反之为负值时,生成左边阴影;y-offset为正值时,生成底部阴影,反之为负值时生成顶部阴影。此例中是一个单边实影投影效果(阴影模糊半径为0),但是如果阴影的模糊半径不是0,上面的方法还能不能实现单边阴影效果呢?不急着来回答,在上面的实例中添加一个模糊半径,例如:
.top {
box-shadow: 0 -2px 5px red;
}
.right {
box-shadow: 2px 0 5px green;
}
.bottom {
box-shadow: 0 2px 5px blue;
}
.left {
box-shadow: -2px 0 5px orange;
}
图3-39说明,这个效果并不是理想的单边阴影效果,当box-shadow添加了5px阴影模糊半径后,阴影不再是实影投影,阴影清晰度向外扩散,更具阴影的效果。但造成了另一个问题,给元素其他三个边加上淡淡的阴影效果,可这并不是设计需要的效果。
那究竟要怎么做呢?此时,box-shadow属性中的阴影扩展半径(spread-radius)会是一个很关键的属性,要实现单边阴影效果,必须配上这个属性(除单边实影之外)。
图3-39 有模糊值的单边阴影效果
.top {
box-shadow: 0 -4px 5px -3px red;
}
.right {
box-shadow: 4px 0 5px -3px green;
}
.bottom {
box-shadow: 0 4px 5px -3px blue;
}
.left {
box-shadow: -4px 0 5px -3px orange;
}
上面的代码调整了阴影的位移量,新增了box-shadow的扩展半径,最终效果如图3-40所示。
注
意 各浏览器下显示效果略有细节差别。
2.四边相同阴影效果
box-shadow给元素设置相同的四边阴影效果,其实分为两种,在这里先看第一种。
(1)只设置阴影模糊半径和阴影颜色
只设置阴影模糊半径和阴影颜色。例如:
.box-shadow{
width: 200px;
height: 100px;
border-radius: 10px;
border: 1px solid #ccc;
margin: 20px;
box-shadow: 0 0 10px #06c;
}
效果如图3-41所示。
在这个示例基础上,添加box-shadow扩展半径还可以控制阴影深度,如果取正值将加深阴影的深度,如果取负值可以向内压缩阴影,直到扩展半径等于模糊半径时,阴影会完全消失。例如:
.box-shadow{
width: 200px;
height: 100px;
border-radius: 10px;
border: 1px solid #ccc;
margin: 20px;
box-shadow: 0 0 10px 10px #06c;
}
效果如图3-42所示。
接下来,将扩展半径改成“-10px”, 此时将看不到任何阴影效果。
.box-shadow{
width: 200px;
height: 100px;
border-radius: 10px;
border: 1px solid #ccc;
margin: 20px;
box-shadow: 0 0 10px -10px #06c;
}
效果如图3-43所示。
(2)只设置扩展半径和阴影颜色
另外一种设置元素四边相同阴影效果,是设置扩展半径和阴影颜色,先来看一个简单的示例。
图3-43 无阴影效果
.box-shadow{
width: 200px;
height: 100px;
border-radius: 10px;
border: 1px solid #ccc;
margin: 20px;
box-shadow: 0 0 0 10px #06c;
}
效果如图3-44所示。
图3-44 四边相同阴影效果
从图3-44可知道,box-shadow制作的阴影效果和元素设置“10px”实线边框一样。
border:10px solid #06c;
如此一来,可以利用box-shadow扩展半径制作类似于边框的效果,但实质上并非边框,因为box-shadow并不是盒模型中的元素,不会计算到内容宽度。具体来看一个box-shadow与border的对比示例。
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>border与box-shadow</title>
<style type="text/css">
.box {
width: 200px;
height: 100px;
text-align: center;
line-height: 100px;
float: left;
margin: 30px;
}
.border{
border: 10px solid red;
}
.box-shadow {
box-shadow: 0 0 0 10px red;
}
</style>
</head>
<body>
<div class="box border">Border</div>
<div class="box box-shadow">Box-shadow</div>
</body>
</html>
效果如图3-45所示。
图3-45 border与box-shadow制作边框效果对比
图3-45证实了box-shadow不会影响页面的任何布局。div.border元素的边框被计算了宽度,但div.box-shadow的阴影被浏览器忽略不计,所以借助box-shadow属性的这个特性,border-shadow用来模拟元素的边框效果可以自由地使用,但必须注意其层级关系。
W3C标准规范中描述了box-shadow的工作方式,直观告诉我们box-shadow在元素盒模型中的层次关系,如图3-46所示。
图3-46告诉我们很多信息,比如说border-radius圆角、阴影扩展、阴影模糊以及padding是如何影响对象的阴影的。非零值的border-radius会以相同的作用影响阴影的外形,但border-image不会影响对象阴影的任何外形;对象阴影同盒模型的层次一样,外阴影会在对象背景之上,内阴影会在边框之下,背景之上。所以整个层级就是:边框在内阴影之上,内阴影在背景图片之上,背景图片在背景色之上,背景色在外阴影之上。
3.内阴影
前几种都是外阴影的使用方法,其实使用inset属性值可以改变元素的阴影类型,将元素的默认外阴影重置为内阴影类型。例如:
.box-shadow {
width: 200px;
height: 100px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: inset 3px 3px 10px #06c;
}
效果如图3-47所示。
图3-47 box-shadow制作内阴影
不过box-shadow的内阴影使用在图片“img”元素上是没有任何效果的,例如:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>图片内阴影效果</title>
<style type="text/css">
img {
box-shadow: inset 5px 5px 10px #06c;
}
</style>
</head>
<body>
<img src="border.jpg" alt="" width="200" />
</body>
</html>
效果如图3-48所示。
图3-48 box-shadow在img上的内阴影无效果
图3-48的效果再次证实了box-shadow的inset内阴影直接运用在img上没有任何效果,但在实际Web项目中难免在图片上添加内阴影的效果。记得将border-radius运用在img上时,Webkit内核浏览器也无效果,最后在img外添加一个容器标签,并将img转换成外容器的背景图片,将border-radius运用在外容器上才有圆角效果的。借助这个思路,也在img标签外添加一个容器,例如“div”标签,但这里不将img转换成div标签的背景,只是将box-shadow的内阴影使用在div标签上,例如:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>图片内阴影效果</title>
<style type="text/css">
.box-shadow {
display: inline-block;/*这个很重要*/
box-shadow: inset 5px 5px 10px #06c;
}
img {
position:relative;/*这个很重要*/
z-index: -1;/*这个很重要*/
vertical-align: top;
}
</style>
</head>
<body>
<div class="box-shadow">
<img src="border.jpg" alt="" width="200" />
</div>
</body>
</html>
此时img就具有内阴影效果了,如图3-49所示。
图3-49 图片内阴影效果
也可以像border-radius制作图片圆角的方法,将图片转为容器div的背景图,也能实现图3-49的效果,但是会使用JavaScript脚本。对于不懂脚本的Web设计师来说,还是蛮头痛的。具体的操作方法可以参考border-radius一节。
4.多层阴影
前几种都是单阴影效果的使用,其实box-shadow可以多层阴影同时使用,每层阴影之间使用逗号“,”隔开。而每层阴影的使用方法都和前面一样,例如:
.box-shadow {
width: 200px;
height: 100px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: -5px 0 5px red, 0 5px 5px blue, 5px 0 5px green, 0 -5px 5px orange;
}
效果如图3-50所示。
制作多层阴影效果时,不设置模糊半径,只设置扩展半径,并配合多个阴影颜色,还可以制作多色边框效果,代替border-color属性制作多色边框效果,例如:
.box-shadow {
width: 200px;
height: 100px;
border: 1px solid #ccc;
margin: 30px;
box-shadow: 0 0 0 1px red,
0 0 0 5px blue,
0 0 0 8px green,
0 0 0 12px yellow,
0 0 0 16px orange,
0 0 0 20px #06c,
0 0 0 24px lime;
}
效果如图3-51所示。
使用box-shadow制作多色边框效果,需要注意模仿border的宽度。前面介绍过box-shadow的工作模式,在计算宽度时需要减去前面阴影的值,才是显示的颜色宽度。
在使用多层级box-shadow时,还需要特别注意阴影的顺序,最先写的阴影将显示在最顶层,如上面的示例,先定义1px红色阴影,再定义5px蓝色阴影,接着是8px绿色阴影,以此类推。显示结果就是红色在蓝色上面,蓝色在绿色上面,绿色在黄色上面,以此类推。但是,如果最前面的阴影太大,顶层的阴影就会遮盖底部的阴影。例如,上例中将最底层的24px的lime阴影放到最前面,效果就完全不一样了。
.box-shadow {
width: 200px;
height: 100px;
border: 1px solid #ccc;
margin: 30px;
box-shadow: 0 0 0 24px lime,
0 0 0 1px red,
0 0 0 5px blue,
0 0 0 8px green,
0 0 0 12px yellow,
0 0 0 16px orange,
0 0 0 20px #06c;
}
此时后面的阴影都被第一个阴影遮盖了,如图3-52所示。
图3-52 被遮盖的阴影效果
3.5.3 浏览器兼容性
目前box-shadow属性得到很好的支持,IE 8及以前版本的浏览器不支持box-shadow属性。在现代浏览器的新版本中无须加各浏览器的前缀,不过要向前兼容,Firefox 3.5~3.6下需要添加“-moz-”,Chrome 4~9和Safari 3.1~5.0浏览器中添加“-webkit”。借助兼容方式,各主流浏览器对box-shadow属性的支持情况如表3-7所示。
表3-7 box-shadow的浏览器兼容表
属性名
box-shadow 9 +√ 3.5 +√ 2.0 +√ 10.5 +√ 4.0 +√
虽然IE低版本不支持这个属性,但目前box-shadow在实际项目中运用越来越普遍。因为box-shadow实现阴影比使用背景图片的方法方便,同时能为Web前端设计师减少很多时间,维护也方便。
要兼容IE低版本,可以使用IE 的滤镜来模拟实现。
filter: progid:DXImageTransform.Microsoft.Shadow(color='颜色值',
Direction=阴影角度(数值), Strength=阴影半径(数值));
其中“DropShadow”(盒状阴影)和“Shadow”(阴影)两个滤镜正是为实现阴影而设,另外“Glow”(发光)滤镜则用于在盒容器四周实现发光阴影。但这些滤镜可设置的参数并不像box-shadow属性那样提供诸多的自定义参数,我不认为这些滤镜能够实现前面示例中所需的效果。当然除了IE滤镜之外,同样可以采用前面说的PIE和IE -CSS3脚本来实现IE 下的阴影效果。
提
示 现代浏览器使用box-shadow来制作阴影,而不支持box-shadow的浏览器让它不显示阴影,如果非要完美兼容,不妨考虑在不支持box-shadow的浏览器中使用背景图片来模仿阴影。
3.5.4 box-shadow属性的优势
从实现盒子阴影来说,box-shadow是最方便的,不管是使用背景图片,还是使用滤镜或者说JavaScript脚本,都无法与box-shadow属性相比。
box-shadow具有多个属性参数可选,能制作出圆润平滑的阴影效果。
代码维护方便,可以随时更改参数来实现效果的更新。
3.5.5 实战体验:制作3D搜索表单
为了方便读者理解,接下来介绍一个box-shadow案例——制作3D搜索表单。
在这个案例中,除了使用box-shadow之外,还使用border-radius制作圆角,并涉及text-shadow制作文本阴影,以及gradient制作渐变背景图片,关于这两项技术,请参阅后面章节。整个案例的效果如图3-53所示。
图3-53 Box-shadow制作3D搜索表单
从box-shadow多层级阴影特性出发,给表单容器设置多个同方向阴影效果,并且配合圆角属性border-radius来描绘圆角线框,同时使用渐变属性制作渐变的背景图片等,结合CSS3的多种效果,从而构建出这个3D搜索表单。
1.构建3D表单的结构
整个表单结构很简单,代码如下所示。
<!—表单结构-->
<form id="formWrapper">
<div class="formFiled clearfix">
<!-- 搜索表单的输入框 -->
<input type="text" required="" placeholder="Search for CSS3, HTML5, jQuery ..." class="search">
<!-- 搜索按钮 -->
<input type="submit" class="btn submit" value="go">
</div>
</form>
整个结构使用一个“form”元素,并且应用一个“div.formFiled”容器来包裹“input.search”的输入框和一个搜索按钮“input.btn”,如图3-54所示。
图3-54 搜索表单结构
2.设计表单容器的3D立体效果
使用box-shadow的多层阴影特性给表单元素设计3D立体效果,样式代码如下所示。
#formWrapper {
width: 450px;/*设置搜索表单的宽度*/
padding: 8px;
margin: 20px;
overflow: hidden;/*清除浮动*/
/*设置表单的边框效果*/
border-width: 1px;
border-style: solid;
border-color: #dedede #bababa #aaa #bababa;
/*最为关键的代码,设置表单3D立体效果*/
box-shadow: 0 3px 3px rgba(255,255,255,.1),
0 3px 0 #bbb, 0 4px 0 #aaa,
0 5px 5px #444;
/*设置圆角效果*/
border-radius: 10px;
/*使用渐变制作表单的渐变背景图片*/
background-color: #f6f6f6;
background-image: -webkit-gradient(linear, left top,
left bottom, from(#f6f6f6), to(#eae8e8));
background-image: -webkit-linear-gradient(top, #f6f6f6, #eae8e8);
background-image: -moz-linear-gradient(top, #f6f6f6, #eae8e8);
background-image: -ms-linear-gradient(top, #f6f6f6, #eae8e8);
background-image: -o-linear-gradient(top, #f6f6f6, #eae8e8);
background-image: linear-gradient(top, #f6f6f6, #eae8e8);
}
3.制作表单输入框的搜索按钮效果
接下来使用box-shadow制作3D立体效果,为了使表单更漂亮,将输入框和搜索按钮进行美化,代码如下所示。
/*输入框样式效果*/
#formWrapper .search {
width: 330px;
height: 20px;
padding: 10px 5px;
float: left;
font: bold 16px 'lucida sans', 'trebuchet MS', 'Tahoma';
border: 1px solid #ccc;
box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #fff;/*多阴影效果*/
border-radius: 3px;
}
/*输入框得到焦点时样式*/
#formWrapper .search:focus {
outline: 0;
border-color: #aaa;
box-shadow: 0 1px 1px #bbb inset;
}
#formWrapper .search::-webkit-input-placeholder,
#formWrapper .search:-moz-placeholder,
#formWrapper .search:-ms-input-placeholder {
color: #999;
font-weight: normal;
}
/*搜索按钮效果*/
#formWrapper .btn {
float: right;
border: 1px solid #00748f;
height: 42px;
width: 100px;
padding: 0;
cursor: pointer;
font: bold 15px Arial, Helvetica;
color: #fafafa;
text-transform: uppercase;
background-color: #0483a0;
background-image: -webkit-gradient(linear, left top,
left bottom, from(#31b2c3), to(#0483a0));
background-image: -webkit-linear-gradient(top, #31b2c3, #0483a0);
background-image: -moz-linear-gradient(top, #31b2c3, #0483a0);
background-image: -ms-linear-gradient(top, #31b2c3, #0483a0);
background-image: -o-linear-gradient(top, #31b2c3, #0483a0);
background-image: linear-gradient(top, #31b2c3, #0483a0);
border-radius: 3px;
text-shadow: 0 1px 0 rgba(0, 0 ,0, .3);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 #fff;
}
/*按钮悬浮状态和焦点状态下效果*/
#formWrapper .btn:hover,
#formWrapper .btn:focus {
background-color: #31b2c3;
background-image: -webkit-gradient(linear, left top,
left bottom, from(#0483a0), to(#31b2c3));
background-image: -webkit-linear-gradient(top, #0483a0, #31b2c3);
background-image: -moz-linear-gradient(top, #0483a0, #31b2c3);
background-image: -ms-linear-gradient(top, #0483a0, #31b2c3);
background-image: -o-linear-gradient(top, #0483a0, #31b2c3);
background-image: linear-gradient(top, #0483a0, #31b2c3);
}
/*按钮点击时效果*/
#formWrapper .btn:active {
outline: 0;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) inset;
}
/*firefox下按钮去除焦点线*/
#formWrapper::-moz-focus-inner {
border: 0;
}
制作的3D立体搜索表单效果如图3-53所示。当然这只是一个简单的案例,box-shadow还可以制作更多的效果,例如双层边框效果、发光效果、立体按钮等。大家还可以发挥自己的想象力,创造出更多的有创意的、有吸引力的UI效果。