关于CSS box-shadow
属性和drop-shadow
过滤器之间的差异与优劣的话题已经不是新鲜事了,box-shadow
属性出现得比较早,它被现代浏览器广泛支持。而drop-shadow
是从SVG中引入CSS的,目前已经被Chrome、Firefox 和 Safari浏览器支持。box-shadow
和drop-shadow
实现的阴影效果是相同的,甚至它们的语法都基本类似。但是仔细观察,会发现它们之间有着显著的差异:
.shadowCSS { box-shadow: 12px 12px 7px rgba(0,0,0,0.5); } .shadowfilter { filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5)); filter: url(shadow.svg#drop-shadow); }
filter
阴影效果都遵从元素的精确外轮廓,甚至是32位和16位的PNG图片,就如上面的显示结果一样。box-shadow
体现的是图像的矩形轮廓,而忽略它们的alpha遮罩层。filter
阴影则是会反映出透明PNG图像的外轮廓。
上面的图像使用border-images
来制作另一个PNG图片的外边框,你可以看到阴影是不规则的,和外边框形状相吻合的阴影效果。
drop-shadow
过滤器会顾及元素的伪元素,如:before
和:after
。看下面纯CSS制作的信息提示框的例子,注意两种方法的提示框下面的小三角形的阴影区别。
drop-shadow过滤器的局限性
下面列举了一下drop-shadow
过滤器的缺点:
dropshadow
过滤器需要四个spread
值来支撑阴影效果(box-shadow
属性亦是如此),但是Webkit内核的浏览器在解析这四个值时有可能会发生解析错误而导致无阴影效果。dropshadow
过滤器不支持inset
值,所以不能通过它来轻易创建内阴影效果。
两种阴影效果的特性差异
这两种阴影效果都顾及border-radius
和transform
。dropshadow
的阴影是一个无背景的透明阴影效果,而box-shadow
的阴影则是一个实心的阴影效果。如果图形的边框不规则,例如是虚线,dropshadow
将会体现出虚线的阴影效果,而box-shadow
则不会。看下面的例子:
border: 3px solid #262b57; width: 150px; height:150px;
border-radius: 10px; transform: rotate(8deg);
box-shadow: 9px 9px 7px rgba(0,0,0,0.3);
filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3));
filter: url(shadow.svg#drop-shadow);
border: 3px dashed #262b57;
box-shadow: 9px 9px 7px rgba(0,0,0,0.3);
filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3));
filter: url(shadow.svg#drop-shadow);
从上面的表现来看,drop-shadow
阴影效果更胜一筹,它只是在内阴影方面有一些缺陷。
两种阴影效果的速度和质量
这两种阴影效果的渲染质量是相同的。在当前支持drop-shadow
过滤器的浏览器中都为其添加了硬件加速的支持,在所以其它因素都相同的情况下,drop-shadow
将会渲染得更快。
结论
那么我们应该使用哪一种来制作阴影效果呢?在目前来说遵循以下几个简单的规则:
- 如果元素是实心的并且是实心边框(
border-radius
可有可无),使用box-shadow
。这种情况下,box-shadow
会被很好的支持,并且得到的效果和drop-shadow
是相同的。 - 如果想这种
inset
内阴影效果,使用box-shadow
。 - 如果是为一张PNG图片且图片有alpha遮罩层,那么可以有几种选择:
- 可以使用photoshop等图像编辑软件来合成阴影效果,这样在所有浏览器中都得到相同的效果。
- 保持图像不变,使用
drop-shadow
来制作阴影,但是这种阴影效果不是跨浏览器的。 - 使用SVG
drop-shadow
过滤器,这种技术可以实现跨浏览器的阴影效果。(这方面内容请看这篇文章中讲解)
“这是使用纯CSS制作的不规则信息提示框和它的阴影效果。”
对于不规则的图形阴影效果,可以使用CSS回退技术来实现阴影效果。
但是要注意一点,这两种阴影渲染方式都会受到该CSS的影响,规则的图形会在兼容浏览器上出现双重阴影的效果。当然,你可以使用之一技术来为老的浏览器提供回退支持,使它们只有box-shadow
。