Bug 313914

Summary: SVG filter not working with <foreignObject> in Safari only
Product: WebKit Reporter: Joe Pea <joe>
Component: SVGAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Blocker CC: karlcow, sabouhallawa, simon.fraser, webkit-bug-importer, zimmermann
Priority: P2 Keywords: InRadar
Version: Safari 26   
Hardware: Mac (Apple Silicon)   
OS: macOS 26   
URL: https://trusktr.github.io/html-liquid-glass
See Also: https://bugs.webkit.org/show_bug.cgi?id=23113
Attachments:
Description Flags
Zipped reproduction with HTML file.
none
Refraction effect working in Chrome.
none
Refraction effect working in Firefox.
none
Refraction effect not working in Safari. none

Joe Pea
Reported 2026-05-02 18:21:46 PDT
Created attachment 479446 [details] Zipped reproduction with HTML file. Not sure if "Blocker" is the correct severity, but for the feature itself I seem to be totally blocked from using it in Safari without a workaround. I am unable to get an SVG filter (f.e. `<feDisplacementMap>`) applied to HTML content inside of an SVG `<foreignObject>` element. Attached are three screenshots of a "Liquid Glass" technique using `<foreignObject>` + `<feDisplacementMap>` in lieu of support for CSS `backdrop-filter` (which only works in Chrome at the moment), one screenshot per browser (Chrome, Firefox, Safari) where only Safari is unable to render the result. To reproduce: - Download the "reproduction.zip" file and unzip it (or clone https://github.com/trusktr/html-liquid-glass and check out commit 3453360b61a601be04c6815bd4b9e0b11f1bb4e3) - go into the folder in a terminal - run a local static HTTP server for the folder (f.e. `npx serve .` with Node.js or `python -m http.server` with Python) - open the result in Safari and see that the first and second examples on the page are not rendering refraction effects. - See the attached screenshots for comparison, or try opening in Chrome and Firefox.
Attachments
Zipped reproduction with HTML file. (2.28 MB, application/zip)
2026-05-02 18:21 PDT, Joe Pea
no flags
Refraction effect working in Chrome. (632.99 KB, image/png)
2026-05-02 18:23 PDT, Joe Pea
no flags
Refraction effect working in Firefox. (803.18 KB, image/png)
2026-05-02 18:23 PDT, Joe Pea
no flags
Refraction effect not working in Safari. (873.82 KB, image/png)
2026-05-02 18:23 PDT, Joe Pea
no flags
Joe Pea
Comment 1 2026-05-02 18:23:01 PDT
Created attachment 479447 [details] Refraction effect working in Chrome. Refraction effect working in Chrome.
Joe Pea
Comment 2 2026-05-02 18:23:25 PDT
Created attachment 479448 [details] Refraction effect working in Firefox.
Joe Pea
Comment 3 2026-05-02 18:23:51 PDT
Created attachment 479449 [details] Refraction effect not working in Safari.
Joe Pea
Comment 4 2026-05-02 18:33:36 PDT
To root out the possibility of browser differences in treatment of security for localhost domains, I published it online where it still works in all browser but Safari: https://trusktr.github.io/html-liquid-glass
Radar WebKit Bug Importer
Comment 5 2026-05-09 18:22:12 PDT
Karl Dubost
Comment 6 2026-05-26 07:18:44 PDT
<svg class="hero-demo-lens" id="hero-demo-html-lens" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice" color-interpolation-filters="sRGB" aria-hidden="true"> <defs> <filter id="hero-demo-html-filter" x="-18%" y="-18%" width="136%" height="136%" color-interpolation-filters="sRGB"> <feGaussianBlur in="SourceGraphic" stdDeviation="0.2" result="blurred_source"></feGaussianBlur> <feImage href="https://trusktr.github.io/html-liquid-glass/hero-displacement-map.png" x="0" y="0" width="200" height="200" result="displacement_map"></feImage> <feDisplacementMap in="blurred_source" in2="displacement_map" scale="178.63115169214103" xChannelSelector="R" yChannelSelector="G" result="displaced"></feDisplacementMap> <feColorMatrix in="displaced" type="saturate" values="6" result="displaced_saturated"></feColorMatrix> <feImage href="https://trusktr.github.io/html-liquid-glass/hero-specular-map.png" x="0" y="0" width="200" height="200" result="specular_layer"></feImage> <feComposite in="displaced_saturated" in2="specular_layer" operator="in" result="specular_saturated"></feComposite> <feComponentTransfer in="specular_layer" result="specular_faded"> <feFuncA type="linear" slope="0.2"></feFuncA> </feComponentTransfer> <feBlend in="specular_saturated" in2="displaced" mode="normal" result="with_saturation"></feBlend> <feBlend in="specular_faded" in2="with_saturation" mode="normal"></feBlend> </filter> </defs> <g filter="url(#hero-demo-html-filter)"> <foreignObject x="0" y="0" width="200" height="200"> <div xmlns="http://www.w3.org/1999/xhtml" style="width:200px;height:200px;overflow:hidden;border-radius:100px;"> <div class="hero-card-stage hero-card-stage--lens" id="hero-demo-html-lens-stage" style="transform: translate(-238px, -97.795px);"> <article class="hero-text-card is-active"> <div class="hero-text-kicker">HTML Backdrop</div> <h2 class="hero-text-title">Liquid glass can bend live text too.</h2> <p class="hero-text-copy">This live version reuses the same layout as the screenshot mock, but keeps the card as ordinary HTML underneath the glass lens.</p> <p class="hero-text-copy">The button stays interactive in the base scene while the lens is rendered from an HTML-only foreignObject overlay above it.</p> <div class="hero-text-actions"> <button class="hero-text-action" type="button" data-hero-html-toggle="true">Activated</button> <div class="hero-text-status" aria-live="polite">Button click reached the live HTML node.</div> </div> </article> </div> </div> </foreignObject> </g> </svg>
Note You need to log in before you can comment on or make changes to this bug.