【问题标题】:CSS backdrop-filter on SVG elementsSVG 元素上的 CSS 背景过滤器
【发布时间】:2018-03-20 10:09:16
【问题描述】:

我正在尝试将backdrop filter 添加到位于另一个 SVG <rect> 之上的 SVG <rect>

但是,CSS 属性 backdrop-filter: blur(10px)-webkit-backdrop-filter: blur(10px) 似乎对 SVG 元素没有任何影响。当我对两个 <div> 执行相同操作时,它可以工作。

两个<rect>怎样才能达到同样的效果呢?

body, html {
  margin: 0;
}

.outerrect {
  position: absolute;
  left: 0px;
  top: 120px;
}

.innerrect {
  position: absolute;
  
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.outerdiv {
  position: absolute;
  left: 0px;
  top: 120px;
  width: 200px;
  height: 100px;
  background-color: red;
}

.innerdiv {
  position: absolute;
  left: 140px;
  top: 20px;
  width: 120px;
  height: 60px;
  border: 1px solid;
  
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
<svg>
  <rect class="outerrect" fill="red" x="0" y="0" width="200" height="100"></rect>
  <rect class="innerrect" x="140" y="20" width="120" height="60"></rect>
</svg>
<div class="outerdiv">
  <div class="innerdiv"></div>
</div>

【问题讨论】:

  • 来自您引用的 MDN 页面:Applies to: all elements; In SVG, it applies to container elements excluding the &lt;defs&gt; element and all graphics elements
  • 所以换句话说就是无法达到我想要的吗?还是我必须使用组并将其应用于它们?
  • 与小组一起玩可能是个好主意

标签: css svg blur css-filters


【解决方案1】:

考虑到滤镜效果模块是非常实验性的并且没有那么广泛地实施(最新的 Edge 和 Chrome 背后的标志),你能做的最好的就是回到 SVG 1.1 滤镜。以下技术看起来很无害,但 Firefox 在背景内容的边界仍然存在问题:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="200">
  <clipPath id="clip">
    <rect id="rect" x="140" y="20" width="120" height="100" />
  </clipPath>
  <filter id="blur" width="160%" height="160%" x="-30%" y="-30%">
    <!-- insert a neutral background color to prevent the backdrop showing
         through blurred regions with alpa < 1 -->
    <feFlood flood-color="#fff" result="neutral"/>
    <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blurred" />
    <feMerge>
      <feMergeNode in="neutral" />
      <feMergeNode in="blurred" />
    </feMerge>
  </filter>
  <!-- group everything you want to include in the backdrop -->
  <g id="backdrop">
    <rect fill="red" x="0" y="0" width="200" height="100" />
    <rect fill="yellow" x="120" y="40" width="40" height="40" />
  </g>
  <!-- make sure the clip-path is applied after the filter -->
  <g style="clip-path: url(#clip)">
    <use xlink:href="#backdrop" style="filter: url(#blur)" />
  </g>
  <use xlink:href="#rect" style="fill:none;stroke:black" />
</svg>

只要您停留在背景图像内足够远的区域并且无需考虑 alpha 值,较短的版本就可以工作:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200">
  <clipPath id="clip">
    <rect id="rect" x="140" y="20" width="120" height="100" />
  </clipPath>
  <filter id="blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blurred" />
  </filter>
  <image id="backdrop" width="400" height="200" href="https://lorempixel.com/400/200/" />
  <g style="clip-path: url(#clip);">
    <use id="overlay" xlink:href="#backdrop" style="filter: url(#blur);" />
  </g>
  <use xlink:href="#rect" style="fill:none;stroke:black" />
</svg>

【讨论】:

  • 非常感谢。您的解决方案效果很好。但是,它看起来仍然有点像解决方法。我希望将来会有更好的解决方案来解决这个问题。
  • 例如,我认为仍然没有办法让这些模糊层堆叠在一起,就像我想要的可视化一样:pasteboard.co/HcYhYyX.png 但目前,我我很高兴... ;)
猜你喜欢
  • 2016-03-06
  • 2019-10-18
  • 2015-02-24
  • 1970-01-01
  • 2019-05-24
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多