图解css3:核心技术与案例实战. 3.5 CSS3盒子阴影属性

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效果。

上一篇:举一反三:跨平台版本迁移之 XTTS 方案操作指南


下一篇:SpringMVC+Swagger UI生成可视图的API文档(详细图解)