投影。 网页设计师长期以来都喜欢它们,以至于我们在 CSS 第 3 级正式将它们引入规范之前,就使用 PNG 图片来模拟它们,作为 box-shadow
属性。 我在工作中仍然经常使用投影,因为它们在某些情况下,例如处理扁平化设计时,可以添加不错的纹理效果。
在 box-shadow
引入不久后,一个 CSS 过滤器 的工作草案出现了,其中包含一种 drop-shadow()
方法,乍一看非常像 box-shadow
。 但是,两者有所不同,值得比较这些差异。
对我来说,主要的差异很早就浮出水面,当时我开始使用 box-shadow
。 这是一个简单的三角形,与我当时制作的三角形类似。
让我们用它来分解两者的区别。
盒阴影
在这个三角形上添加一个 box-shadow
,就会发生这种情况。
这很烦人,但合乎逻辑。 CSS 使用 盒模型,其中元素的边缘以矩形的形状绑定在一起。 即使在元素形状似乎不是盒子时,盒子仍然存在,这就是 box-shadow
应用于的地方。 这是我在了解 box-shadow
中的“盒”时,我的 “顿悟时刻”。
CSS 过滤器投影
CSS 过滤器非常棒。 看看 所有可能性,以便在元素上添加视觉过滤器,并惊叹于 CSS 如何突然开始做很多我们以前必须在 Photoshop 中模拟的事情。
过滤器不受盒模型的约束。 这意味着我们的三角形轮廓会被识别,周围的透明度会被忽略,以便目标形状接收阴影。
决定使用哪种方法
答案完全取决于你。 上面三角形的简单示例可能让人觉得 filter: drop-shadow()
更好,但它并没有公平地比较两种方法的优势,甚至没有比较它们的可能性。 它仅仅是在特定上下文中对其不同行为的说明。
就像开发中的大多数事情一样,使用哪种方法的答案取决于具体情况。 以下是一个并排比较,帮助区分两者,以及何时最好选择其中一种而不是另一种。
盒阴影 | 投影 | |
---|---|---|
规范 | CSS 背景和边框模块级别 3 | 过滤器效果模块级别 1 |
浏览器支持 | 很棒 | 良好 |
支持扩散半径 | 是的,作为可选的第四个值 | 否 |
模糊半径 | 计算基于像素长度 | 计算基于 SVG 过滤器的 stdDeviation 属性 |
支持 inset 阴影 | 是 | 否 |
性能 | 不使用硬件加速 | 在支持它的浏览器中使用硬件加速。 没有硬件加速,它会很繁重。 |
总结
box-shadow
和 filter: drop-shadow()
之间的区别实际上归结为 CSS 盒模型。 一个看到它,另一个忽略它。 在浏览器支持、性能等方面,还有其他差异来区分两者,但两者处理盒模型的方式是关键区别。
更新: Amelia 在 评论中 指出了另一个关键区别,即 drop-shadow()
的半径扩散计算方式不同于 box-shadow
甚至 text-shadow
。 这意味着在 box-shadow
中指定的扩散半径与 drop-shadow
的默认扩散值不完全一致,因此在某些情况下,两者不能互换。
让我们通过一些其他很棒的示例来说明这一点。 Lennart Schoors 也写了一篇不错的文章,使用工具提示和图标作为实际示例,这些示例我们 之前 提到过。
我真的希望盒阴影和投影之间的模糊半径一致。 两种方法使用相同的模糊量会产生不同的视觉效果。
更正
drop-shadow()
过滤器不接受用于增加扩散的第四个参数——这不是仅仅是浏览器支持问题。 来自规范这样一来,它更像是
text-shadow
而不是box-shadow
。 它通过模糊和偏移现有图形(已经转换为像素)来工作,而不是生成一个新的模糊框。以及一个额外的警告
drop-shadow()
的模糊参数与text-shadow
和box-shadow
中使用的参数不一致。 相反,它是一个“标准差”值(等效于 SVG 过滤器中的stdDeviation
属性),并且是阴影属性中使用的模糊半径的 一半。换句话说,
filter: drop-shadow(0 0 30px #333)
的模糊程度是box-shadow: 0 0 30px #333;
的 两倍。在我看来,这种差异非常不幸,但所有浏览器对
drop-shadow()
的实现都一致,因此规范不太可能改变它。 (在此处讨论)感谢 @AmeliaBR 关于模糊差异的后续说明。 我知道它不对,但没有意识到它是两倍/一半的关系。
啊,感谢更正,Amelia! 我必须承认,我对官方规范中关于扩散值的说明和 MDN 中的说明感到困惑。 我已经更正了帖子中的信息。
你的警告也很到位,确保也提到了这一点。 :)
干杯!
Geoff
哈哈,你的图片很精彩,“看着代码的未来”
酷!
我试了一下。 我应该提到的唯一问题是投影缺乏抗锯齿,如果我在移动设备上放大它,看起来会有锯齿。
虽然投影过滤器不支持用逗号分隔的多个值,但 CSS 属性过滤器确实允许在它的值中使用多个过滤器,并且没有任何东西可以阻止它在它的参数中使用相同类型的过滤器,但具有不同的值。
我的意思是,可以在同一个 CSS 声明中多次使用
drop-shadow()
filter: drop-shadow(xxx) drop-shadow(zzz);
感谢你包括这些老式矿井笔,Geoff。
此致。
好点。 它让我想起你也可以堆叠盒阴影,人们用它来制作 3D 对象。 文本阴影也是如此。 你也可以将盒阴影应用于:伪元素,减少额外的标记。 说实话,你也可以对其进行动画处理(过去在:伪元素上进行动画处理并不一致,但我猜现在可以了)!
你可以在此处看到演示之一:http://blogs.sitepointstatic.com/examples/tech/css3-3d-text/index.html
唯一剩下的问题是它的渲染有多重。 必须有人进行计算才能给出答案。
和平!
我以前从未在 filter 属性中使用过 drop-shadow()。这是一个惊人的发现,所以这是我的第一次探索:https://codepen.io/o-k-s-a-n-a/pen/oGroMv
今天我学到了新东西。Coo。谢谢,你让我的今天过得很愉快。