Consider the following example (adapted from here), which applies the same feTurbulence
/feDisplacementMap
SVG filter to two HTML elements, one as a CSS filter()
and one as a CSS backdrop-filter()
. On Chrome, the distortion is applied correctly to both elements, but on Firefox/Safari only the element using filter()
is distorted, while the element using backdrop-filter()
is unaffected.
.modal {
background-color: rgba(255, 255, 255, 0.95);
border-radius: 5px;
color: #333;
font-family: sans-serif;
line-height: 1.5;
max-width: 50%;
padding: 1rem 2rem;
backdrop-filter: url(#filter-turbulence);
background-color: rgba(255, 255, 255, 0.5);
}
.modal p:last-child {
filter: url(#filter-turbulence);
}
/* misc. irrelevant styles for demo */
html, body { height: 100%; width: 100%; } body { background-image: url('https://41.media.tumblr.com/efd15be8d41b12a7b0ef17fba27c3e20/tumblr_mqqy59HMaf1qzattso1_1280.jpg'); background-position: center center; background-repeat: no-repeat; background-size: cover; } .container { align-items: center; display: flex; justify-content: center; height: 100%; width: 100%; } a { color: #bf0222; }
<svg height="0">
<defs>
<filter id="filter-turbulence">
<feTurbulence
type="turbulence"
baseFrequency="0.01"
numOctaves="4"
result="turbulence"
/>
<feDisplacementMap
in2="turbulence"
in="SourceGraphic"
scale="30"
xChannelSelector="R"
yChannelSelector="G"
/>
</filter>
</defs>
</svg>
<div >
<div >
<p>The background behind these paragraphs uses a SVG filter with backdrop-filter(). The background behind it should be distorted.</p>
<p>This paragraph uses a SVG filter with filter(). The text should be distorted.</p>
</div>
</div>
I’ve been having trouble debugging this issue since Safari and Firefox do accept the filter in filter()
, just not in backdrop-filter()
, and since no error messages are produced on either browser in the console or in the CSS inspector.
I’ve tried simpler SVG filters to verify that Chrome and Safari do support SVG backdrop-filters: simple effects like blur/desaturate work properly. However, I’ve been unable to get any combination of feTurbulence
and/or feDisplacement
to render in a backdrop-filter in either browser.
Is there some obvious way I’m mis-defining my filters that Chromium tolerates but other browsers do not? Is there some known limitation in other browsers’ backdrop-filter implementations that I’ve been unable to find documented?
CodePudding user response:
In Firefox backdrop-filter is only supported in the graphics path called webrender.
Unfortunately webrender currently only supports CSS filters but if we can define an SVG filter chain in terms of CSS filters (together with some other clipping restrictions) then we can do backdrop-filtering with SVG (and CSS filters). If we can't then we give up.
So the presence of a filter element such as feComponentTransfer that has no CSS filter equivalent causes the whole backdrop-filter to fail. But a filter such as feGaussianBlur that we can convert to blur() is OK.
At some point I imagine we'll extend the scope of webrender to implement more SVG filters.