如何通过 CSS 将阴影过滤器应用于 SVG 特定元素/路径
Posted
技术标签:
【中文标题】如何通过 CSS 将阴影过滤器应用于 SVG 特定元素/路径【英文标题】:How to apply drop-shadow filter via CSS to SVG specific element/path 【发布时间】:2016-03-31 08:02:16 【问题描述】:我想通过 CSS 将阴影过滤器应用于内联放置的 SVG 内的特定元素/路径,我不需要需要对整个图形进行阴影处理,只需一个元素在里面。
.shadow
fill: red;
-webkit-filter:
drop-shadow( 3px 3px 2px rgba(0,0,0,.7) );
filter:
drop-shadow( 3px 3px 2px rgba(0,0,0,.7) );
<svg >
<g>
<path d="M0,0 C-72,132 -72,-26 100,100"></path>
</g>
<g class="shadow" >
<circle class="shadow" cx="100" cy="100" r="20"></circle>
</g>
</svg>
正如您在上面看到的,我正在尝试对 SVG 的红色圆圈元素应用投影,但它不起作用。
四处搜索我没有找到任何具体信息,only few comments 在其他 SVG 相关问题中只是说明它不适用于单个 SVG 元素,但没有太多解释。
更新
正如 cmets 中的 @azeós 所指出的,它在 Firefox (v. 43.0.2) 中可以正确呈现,因此这是 Chrome 特有的问题。有没有办法在不摆弄 cmets 中建议的 SVG 代码的情况下制作这个跨浏览器?
【问题讨论】:
只是好奇,为什么不用 SVG 过滤器来创建阴影? 就像 Harry 建议的那样,我认为投影的最佳选择是 svg 代码中的过滤器 w3schools.com/svg/svg_feoffset.asp 是的,应该在问题中指定,我想避免由于工作流程而弄乱 SVG 代码。这真的是唯一可行的选择吗? 我看到了阴影... Waterfox 40.1.0,您使用的是哪个浏览器? ***.com/a/13624469/1095101 哦,太好了,我正在使用 chrome,我也可以在 Firefox 上看到阴影。我想那是 Chrome 的业务。 chrome的具体问题是什么?我已经更新了问题 【参考方案1】:2020 年 4 月更新:我在这个问题上做了一些实验,因为我也找不到这方面的任何信息,结果也很不一致。
TL;DR:SVG 阴影非常不一致,但 HTML 阴影可以可靠地工作(在 IE11 之外)。如果你想要 SVG 阴影,you're going to have use a polyfill 或者只是做SVG 本身内的阴影。
Codepen 实验: http://codepen.io/staypuftman/pen/GoNoMq
Chrome 81 + 金丝雀 83:
Chrome 和 Edge Canary 都不尊重 filter
或 -webkit-filter
在 SVG 对象投影的上下文中正确,但可以在简单的 div
上工作。
Firefox 75 + Firefox 53(前量子):
对于 SVG 和 html 对象看起来都不错。
Safari 13+
Safari 在早期版本中曾短暂地出现过阴影,但后来又删除了。
Safari 10.1 - 11
Safari 已在 10.1(可能还有 10.0)系列中修复了此问题。
Safari 9.x
SVG CSS 阴影不显示,div
阴影由于某种原因不透明度较低
Edge(铬版)
没有 SVG 阴影,但 HTML 效果很好。
IE11
什么都没有。
【讨论】:
有趣的研究,谢谢!我无法在 polyfill 上测试自己,你能确认它也在 chrome 上工作吗? 我还没有尝试过polyfill,我明天必须这样做,因为我在我的时区完成了一天。如果你试一试,请告诉我。【参考方案2】:您可以通过对要阴影的对象进行颜色选择,创建阴影然后将其合并到原始图形下来选择性地应用阴影。但是您必须通过 CSS 过滤器中的 SVG 过滤器陷门来完成 - 这在 IE 中不起作用。 (所以...... hacky,但可能)
规格在这里:w3.org/TR/SVG11/filters.html#feColorMatrixElement
演示玩具在这里:https://beta.observablehq.com/@gitmullany/filter-effects-using-svg-color-matrices
该矩阵将所有红色值的不透明度加倍,将其他所有值的不透明度归零,然后减去 1。效果是只保留 rgb(255,0,0) 的 100% 不透明度
#mySVG
filter: url(#selective-shadow);
.shadow
fill: red;
<svg>
<defs>
<filter id="selective-shadow">
<feColorMatrix type="matrix" values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
2 0 0 0 -1"/>
<feGaussianBlur stdDeviation="3"/>
<feOffset dy="2" dx="2"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<svg id="mySVG">
<g>
<path d="M0,0 C-72,132 -72,-26 100,100"></path>
</g>
<g class="shadow" >
<circle class="shadow" cx="100" cy="100" r="20"></circle>
</g>
</svg>
【讨论】:
哦,哇,这是一些高级的 SVG 黑客技术,据我所知,它有效!很不错!请问那个矩阵网格东西的文档在哪里? :) 规格在这里:w3.org/TR/SVG11/filters.html#feColorMatrixElement 演示玩具在这里:beta.observablehq.com/@gitmullany/…。该矩阵将所有红色值的不透明度加倍,将其他所有值的不透明度归零,然后减去 1。效果是只保留 rgb(255,0,0) 的 100% 不透明度 神圣的SVG!!我不知道你可以用 SVG 做这样的事情,该死的猜想我需要对这个主题进行一些更新 x)谢谢!【参考方案3】:在this CodePen 我添加了不同的drop-shadows 到动态生成的path
和text
。 Here 我找到了一个跨浏览器解决方案,例如,您可以将其应用于class
,而不是#robbie img
(在第二个链接中):
#robbie img filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')"; filter: url(#drop-shadow); -webkit-filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5)); filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5));
在first CodePen 中,我评论了另一种不使用类 的替代方法,但它使用<defs></defs>
中定义的#numbers_dropshadows_filter
和#strokes_dropshadows_filter
。
干杯
【讨论】:
以上是关于如何通过 CSS 将阴影过滤器应用于 SVG 特定元素/路径的主要内容,如果未能解决你的问题,请参考以下文章