CSS揭秘
上QQ阅读APP看书,第一时间看更新

2 多重边框

背景知识

box-shadow的基本用法

难题

回首往事,当背景与边框第三版)(http://w3.org/TR/css3-background)还在草案阶段时,CSS工作组内部有过很多讨论,关于是否应该允许多重边框,就像多重背景那样。不幸的是,当时一致认为这个特性并没有足够多的使用场景,而且网页开发者还可以使用border-image来达到相同的效果。然而工作组忽略了一点:我们通常希望在CSS代码层面以更灵活的方式来调整边框样式。因此,网页开发者们最终不得不折腾出各种丑陋的hack,比如使用多个元素来模拟多重边框。不过,我们还有更好的办法来解决这个难题,并不需要添加无用的额外元素来污染我们的结构。

图2-5

用box-shadow来模拟外框

box-shadow方案

目前为止,我们大多数人可能已经用过(或滥用过)box-shadow来生成投影。不太为人所知的是,它还接受第四个参数(称作“扩张半径”),通过指定正值或负值,可以让投影面积加大或者减小。一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,得到的“投影”其实就像一道实线边框(参见图2-5):

background:yellowgreen;
box-shadow:0 0 0 10px #655;

这并没有什么了不起的,因为你完全可以用border属性来生成完全一样的边框效果。不过box-shadow的好处在于,它支持逗号分隔语法,我们可以创建任意数量的投影。因此,我们可以非常轻松地在上面的示例中再加上一道deeppink颜色的“边框”:

background:yellowgreen;
box-shadow:0 0 0 10px #655,0 0 0 15px deeppink;

唯一需要注意的是,box-shadow是层层叠加的,第一层投影位于最顶层,依次类推。因此,你需要按此规律调整扩张半径。比如说,在前面的代码中,我们想在外圈再加一道5px的外框,那就需要指定扩张半径的值为15px(10px+5px)。如果你愿意,甚至还可以在这些“边框”的底下再加一层常规的投影:

background:yellowgreen;
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关键字,来使投影绘制在元素的内圈。请注意,此时你需要增加额外的内边距来腾出足够的空隙。

试一试 play.csssecrets.io/multiple-borders


outline方案

在某些情况下,你可能只需要两层边框,那就可以先设置一层常规边框,再加上outline(描边)属性来产生外层的边框。这种方法的一大优点在于边框样式十分灵活,不像上面的box-shadow方案只能模拟实线边框(假设我们需要产生虚线边框效果,box-shadow就没辙了)。如果要得到图2-6的效果,代码可以这样写:

图2-6

使用box-shadow来模拟双层外框

图2-7

在这些“外框”下再添加一层真实的投影效果

图2-8

对一层dashed(虚线)描边使用负的outline-offset后,可以得到简单的缝边效果

图2-9

通过outline属性实现的“边框”不会贴合元素的圆角,不过这一行为在未来可能会发生变化

background:yellowgreen;
border:10px solid #655;
outline:5px solid deeppink;

描边的另一个好处在于,你可以通过outline-offset属性来控制它跟元素边缘之间的间距,这个属性甚至可以接受负值。这对于某些效果来说非常有用。举个例子,图2-8就实现了简单的缝边效果。

这个方案同样也有一些需要注意的地方。

如上所述,它只适用于双层“边框”的场景,因为outline并不能接受用逗号分隔的多个值。如果我们需要获得更多层的边框,前一种方案就是我们唯一的选择了。

边框不一定会贴合border-radius属性产生的圆角,因此如果元素是圆角的,它的描边可能还是直角的(参见图2-9)。请注意,这种行为被CSS工作组认为是一个bug,因此未来可能会改为贴合border-radius圆角。

根据CSS基本UI特性(第三版)规范(http://w3.org/TR/css3-ui)所述,“描边可以不是矩形”。尽管在绝大多数情况下,描边都是矩形的,但如果你想使用这个方法,请切记:最好在不同浏览器中完整地测试最终效果。

相关规范


CSS背景与边框

http://w3.org/TR/css-backgrounds


CSS基本UI特性

http://w3.org/TR/css3-ui