【问题标题】:SVG filter from another invisible SVG removes target completely来自另一个不可见 SVG 的 SVG 过滤器完全移除目标
【发布时间】:2020-01-31 10:42:08
【问题描述】:

所以我的页面上有 2 个 SVG 元素:一个带有路径,另一个带有过滤器(我这样做是为了能够将该过滤器应用于多个 SVG

<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 1 1 " class="filter-target">
  <path filter="url(#glow)" d="M 0,0 v 1 h 1 v-1 h-1 z" />
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1 1" class="filter-source">
  <defs>
    <filter id="glow">
      <feFlood flood-color="rgb(0,0,255)" in="SourceAlpha" result="makeBlue" />
      <feMerge>
        <feMergeNode in="makeBlue"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
  </defs>
</svg>

一切都很好,但后来我决定隐藏第二个 SVG 以防止出现布局问题。所以我做了以下CSS:

.filter-source {
  display: none;
}
.filter-target {
  width: 40px;
  height: 40px;
  border: 1px red dashed;
}

因此,带有filter 属性的path 也消失了,就像浏览器完全删除了第二个SVG 而不是隐藏一样。

在 Linux 下的 Chrome 76 和 Firefox 60 上得到了同样的效果。

是错误还是规范?

Fiddle is here

【问题讨论】:

  • 规范正在发生变化,以反映浏览器不会/不能按照书面形式实现它的现实。如果你使用 display: none 你的效果(过滤器/剪辑路径/蒙版)将不起作用。
  • 某种魔法..

标签: css svg svg-filters


【解决方案1】:

过滤器继承属性display: none,因此可见svg 中不会显示任何内容。我认为您应该删除 .filter-source css 代码,只需将 width="0" height="0" 添加到第二个 svg:

.filter-target {
  width: 40px;
  height: 40px;
  border: 1px red dashed;
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 1 1 " class="filter-target">
  <path filter="url(#glow)" d="M 0,0 v 1 h 1 v-1 h-1 z" />
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1 1" class="filter-source" width="0" height="0">
  <defs>
    <filter id="glow">
      <feFlood flood-color="rgb(0,0,255)" in="SourceAlpha" result="makeBlue" />
      <feMerge>
        <feMergeNode in="makeBlue"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
  </defs>
</svg>
Now the layout is not interrumpted

在 cmets 之后编辑

  1. Why path stays visible when I return display:none back? 这是一个关于浏览器行为的问题。我看到它发生在 Chrome 中,但不是在 Firefox 中。显然,正确的行为是 Firefox。

  2. documentation you referenced says "it does not prevent elements from being referenced by other elements" 该元素被引用,但其display 属性为none,这就是您看不到颜色的原因。您正在应用一个不可见的过滤器。

  3. display property is not inherited 文件第三段内容如下:

    当应用于容器元素时,将 display 设置为 none 会导致 容器及其所有子项是不可见的;因此,它作用于群体 作为一个组的元素。这意味着一个元素的任何子元素 display="none" 永远不会被渲染,即使孩子的值为 显示非无。

请记住,我们谈论的是 svg display,而不是 css display

【讨论】:

  • 我已经用类似的技巧使.filter-source不可见,所以问题更多的是关于这种特殊行为。真正奇怪的是,如果我使用开发者控制台将display: block添加到.filter-source然后删除它, .filter-target 内容变得可见
  • 正如我在答案中所说,display 属性是继承的,这意味着您的过滤器具有属性display="none"。这按预期工作。您可以在developer.mozilla.org/en-US/docs/Web/SVG/Attribute/display 看到更多详细信息。如果您删除display 属性,默认值为inline,因此它应该被渲染。
  • 为什么path 在我返回display:none 时仍然可见?
  • 另外,还有两件事:1)您引用的文档说“它不会阻止元素被其他元素引用”,以及 2)display 属性未继承
  • 完全同意,似乎浏览器确实跳过了应用隐形过滤器,但我仍然找不到任何规范可以在这里应用。一切都是关于渲染元素本身,而不是关于它如何影响 其他 元素。
猜你喜欢
  • 1970-01-01
  • 2019-12-23
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2019-07-07
  • 2013-01-02
相关资源
最近更新 更多