有些情况下,为了满足一些要求,普通的边框有点达不到我们的需求,这时我们可以使用多重边框。
背景知识
box-shadow(盒子阴影)的基本用法
box-shadow属性可以设置一个或多个下拉阴影的框。
语法:
box-shadow: h-shadow v-shadow blur spread color inset;
值 | 说明 |
---|---|
h-shadow | 必需的。水平阴影的位置。允许负值 |
v-shadow | 必需的。垂直阴影的位置。允许负值 |
blur | 可选。模糊距离 |
spread | 可选。阴影的大小 |
corlor | 可选。阴影的颜色。在CSS颜色值寻找颜色值的完整列表 |
inset | 可选。从外层的阴影(开始时)改变阴影内侧阴影 |
难题
在背景与边框(第三版)还在草案阶段时,CSS工作组中有过讨论,关于是否应允许多重边框,就如多重背景一般,当时一致认为这个特性没有足够多的使用场景,而且网页开发者还可以使用border-image来达到相同的效果。然而当时研究的工作组成员却忽略了这一点:我们通常希望在CSS代码层面以更灵活的方式来调整边框样式。因此,网页开发者最终不得不折腾出各种丑陋的hack,比如使用多个元素来模拟多重边框。不过,我们还有更好的办法来解决这个难题,并不需要添加无用的额外元素来污染我们的结构。
box-shadow方案
众所周知,box-shadow可以生成投影。不过,不太被人所知的是,他还接受第四个参数(称作“扩张半径”),通过指定正值或负值,可以让投影面积变大或减小。一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,得到的“投影”其实就像一道实现边框(图一)。
background:white;
box-shadow: 0 0 0 10px #655;
但是这种效果没什么大不了,你用border属性也可以生成一个一样的边框效果。不过使用box-shadow的好处是,它支持逗号分隔语法,我们可以创建任意数量的投影。因此,我们可以继续的的之前的示例中再加上一道deeppink的“边框”:
background:white;
box-shadow: 0 0 0 10px #655,0 0 0 15px deeppink;
从图片可以看出,新添加的边框只可以看到5像素的宽度,这一点是需要注意的,box-shadow是层层叠加的,第一层投影位于最顶层,以此类推。因此,在添加新边框时,你需要按照此规律调整扩张半径。比如说,在前面的代码中,我们想在外圈再加一道5px的外框,那就需要指定扩张半径的值为15px(10px+5px)。
这些边框下面也可以加一些常规的投影:
background:white;
box-shadow: 0 0 0 10px #655,
0 0 0 15px deeppink,
0 2px 5px 15px rgba(0,0,0,.6);
多重投影解决方案在绝大多数场合都可以很好地工作,但有一些注意事项。
- 投影的行为跟边框不完全一致,因为它不会影响布局,而且也不会受到box-sizing属性的影响。不过,你还是可以通过内边距或外边距(这取决于投影是内嵌还是外扩的)来模拟出边框所需要占据的空间。
- 上述方法所创建的假“边框”出现在元素的外圈。它们并不会响应鼠标事件,比如悬停或点击。如果这一点非常重要,你可以给box-shadow属性加上inset关键字,来使投影绘制在元素的内圈。请注意,此时你需要增加额外的内边距来腾出足够的空隙。
outline方案
当你只需要两层边框时,那就可以先设置一层常规边框,再加上outline(描边)属性来产生外层的边框。这种方法更具多样性,不仅可以模拟实线边框,也可以产生虚线边框效果。
background:white;
border: 10px solid #655;
outline: 5px solid deeppink;
这个与上面的效果是一样的。
描边的另一个好处是,可以通过outline-offset属性来控制它跟元素边缘之间的间距,这个属性甚至可以接受负值,这对于某些效果非常有用。
本方案也有需要注意的地方。
- outline只适用于双层“边框”的场景,因为outline并不能接受用逗号分隔的多个值。如果我们需要获得更多层的边框,前一种方案就是我们唯一的选择了。
- 边框不一定会贴合border-radius属性产生的圆角,因此如果元素是圆角的,它的描边可能还是直角的。请注意,这种行为被CSS工作组认为是一个Bug,因此未来可能会改为贴合border-radius圆角。
- 根据CSS基本UI特性(第三版)规范(http://w3.org/TR/css3-ui)所述,“描边可以不是矩形”。尽管在绝大多数情况下,描边都是矩形的,但如果你想使用这个办法,请切记:最好在不同浏览器中完善地测试最终效果。