用CSS实现的阴影效果

“…假如有一种技术,用 CSS 对任意块级元素灵活地添加阴影,而且能随着内容的大小自动扩展,还要适用于大多数流行的浏览器,那该有多好!不信么?告诉您,只需写几行代码就能做到。”

阴影效果成了平面设计的一个套路,平面设计师把它当作瑞士军刀的起子,随处使用,尽管招致不少非议,却一直广受欢迎。虽然用图像编辑软件也能实现阴影效果,但在Web设计快速发展的今天,适应性和易用性是大势所趋,这种以固定背景效果制作出的静态图片很难有良好的适应性。

假如有一种技术,用 CSS 对任意块级元素灵活地添加阴影,而且能随着内容的大小自动扩展,还要适用于大多数流行的浏览器,那该有多好!不信么?告诉您,只需写几行代码就能做到。

是不是很有意思?先别急,这可不是我们的发明,我们只不过对此作了改进。这个技术是由著名的 1976 design 上的 Dunstan Orchard (向 Dunstan 脱帽致敬)构思出来的,并且作了演示。我们觉得这个方法简洁实用,但深入研究之后,发现还有改进的余地。

这里是它的工作原理:先用图像软件制作一幅背景图片,图片上只有阴影,不能有可见的边界(一种简便的方法是对空白的选择区域应用某种效果)。这个图片要能够覆盖将要修饰的最大元素,实践当中,800 x 600 一般就足够了。将它保存为GIF图片,记住一定要在背景颜色之上应用效果,此外再把它另存为完全透明的PNG图片(即没有背景色)。这是为了根据浏览器的能力区别对待[译注:即让支持透明 PNG 图片的浏览器使用PNG,IE 使用GIF。]。这里是将要用到的 GIF 文件以及 PNG 文件

 

test

我们先从如何为图片添加阴影开始,然后再扩展到其他块级元素。为了直观起见,我们把这个 class 命名为 img-shadow,我们先用这只可爱的小猫作个试验:

相应的代码(只需额外增加一个 div ):

<div class="img-shadow">
<img src="cat.jpg" alt="test"/>
</div>

下图演示了我们所用到的技术:

 

Technique illustration


 

首先,我们用先前准备的阴影图片作为该 div 的背景。

background: url(shadow.gif) no-repeat bottom right;

然后,我们将图片的左边距和上边距设为负值,使它“投下”阴影,阴影的宽度为 6 个像素,也就代码中的数字:

margin: -6px 6px 6px -6px;

为避免指定该 div 的大小,我们将它浮动起来。(否则它将占据全部可用的水平空间。)

还记得前面我们说过,要让好的浏览器显示好的阴影效果吗?诀窍在这行代码:

background: url(shadowAlpha.png) no-repeat right bottom !important;

这里的“!important”表示此处指定的样式的优先级高于同元素上的普通样式声明(参见 标准),对透明 PNG 缺乏内在支持的所有版本的 Internet Explorer 刚好也不支持“!importan”。通过互相矛盾的两次声明,我们得到了期望的结果(IE 用的是第二个,而大多数浏览器会采用第一个)。最终的结果是这样的:当需要改变背景颜色时,支持 PNG 的浏览器显示出的阴影效果非常完美。而在可怜的 IE 中,阴影还是它原来的颜色。

你可能会问,为什么要这样做?答案是可以一箭双雕。

  • 我们能够: 不费吹灰之力就可以自动地让高级的浏览器发挥它的最好效果。
  • 它能自我修复: 如果(随Longhorn而来的)新版 Internet Explorer 支持这两个标准,我们无须进行修补,仍然能够获得精确、完全透明的阴影。

最终的 CSS 代码是这样的:

.img-shadow {
float:left;
background: url(shadowAlpha.png) no-repeat bottom right !important;
background: url(shadow.gif) no-repeat bottom right;
margin: 10px 0 0 10px !important;
margin: 10px 0 0 5px;
}
.img-shadow img {
display: block;
position: relative;
background-color: #fff;
border: 1px solid #a9a9a9;
margin: -6px 6px 6px -6px;
padding: 4px;
}

为了补偿 IE 浮动模型的错误,所以上面代码中的 margin 有些差异,而最后一行的 padding 将图片框装扮得更加漂亮,可惜在 IE 5.0 和 5.5 中不起作用,不过阴影效果仍然存在。

在符合标准的浏览器中,阴影和背景无缝融合在一起。在 IE 中,除非你把阴影和背景设为同一颜色,否则阴影和背景的过渡就显得比较生硬。这里就是最终效果:[译注:请在不同的浏览器中观看效果。]

 

A cute cat

 

A cute cat

接下来让我们为一段文字加上阴影效果。

一段文字只不过是一个区块元素,按理说上面的技术应该同样适用。实际上,在大多数浏览器中都没问题,猜猜看,到底是哪个浏览器搞的破坏?

在开发这种技术时,我们发现如果要应付的不是图片,而是一个块级元素,则难度之大超出了我们的想象。不管我们如何尝试,IE 总是把左上角(也就是“突出”阴影之外的部分)给切掉。更可笑的是,只有 5.0 版的 IE 表现正常。看来任何技巧、溢出设定或者建议都于事无补(当然也试过念咒语)。我们决定放弃,转而寻求别的解决方案。

我们先从 Douglas Bowman 的Sliding Doors(滑门)方法开始,当然额外的开销(另一个 div)必须要有,我们的这个段落应该是这个样子:

<div class="p-shadow">
<div>
<p>The rain in Spain ...</p>
</div>
</div>

与刚才指定负的左、上边距(margin)值的做法相反,这回我们为右、下边距(padding)指定正值,将阴影(其实是外层 div 的背景)暴露出来。然后,我们用一个局部透明的 GIF 图片放在阴影之上,伪造出的阴影偏移效果。注意,图片可见部分的颜色要与用于阴影效果的背景颜色相同。这幅图片的名字为 “shadow2.gif”。图片的构成如下:

 

Fake offset image example


 

这就是GIF 图片的例子(这幅图片在浏览器的中看起来好像是空白的,所以最好把它存起来,在图形处理软件中观看。)

这就是我们想要达到的效果:

 

Paragraph technique illustration


 

下面是实现这种效果的样式表。注意额外的图片和补白(padding)仅仅用于 Internet Explorer。绝大多数浏览器会忽略内层的 div,仍然使用前面讲过的图片阴影效果技术。

.p-shadow {
width: 90%;
float:left;
background: url(shadowAlpha.png) no-repeat bottom right !important;
background: url(shadow.gif) no-repeat bottom right;
margin: 10px 0 0 10px !important;
margin: 10px 0 0 5px;
}
.p-shadow div {
background: none !important;
background: url(shadow2.gif) no-repeat left top;
padding: 0 !important;
padding: 0 6px 6px 0;
}
.p-shadow p {
color: #777;
background-color: #fff;
font: italic 1em georgia, serif;
border: 1px solid #a9a9a9;
padding: 4px;
margin: -6px 6px 6px -6px !important;
margin: 0;
}

在前面的图片例子中提到的背景色注意事项,段落也应加以注意。这就是最终的效果。(请试着改变浏览器窗口大小,观察段落大小的改变和阴影的调整。)

posted @ 2008-06-10 17:55  小魔鬼  阅读(4091)  评论(1)    收藏  举报