Bug 314999

Summary: SVG filter applied with CSS to element below viewport renders spurious black square
Product: WebKit Reporter: account+webkit-bugzilla <account+webkit-bugzilla>
Component: SVGAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Normal CC: bfulgham, karlcow, sabouhallawa, simon.fraser, webkit-bug-importer, zalan, zimmermann
Priority: P2 Keywords: InRadar
Version: Safari 26   
Hardware: iPhone / iPad   
OS: iOS 26   
Attachments:
Description Flags
testcase
none
rendering in safari, firefox, chrome none

account+webkit-bugzilla@boermans.name
Reported 2026-05-17 21:50:43 PDT
Spurious black box rendered in top left of viewport on iOS when SVG filter applied to offscreen element (scrolled below visible viewport). My reduced repo: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>svg filter bug</title> <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg></svg>" /> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div style="height: 100vh"></div> <div style="filter: url('#blur')">Filter target</div> <svg color-interpolation-filters="sRGB"> <defs> <filter id="blur"> <feGaussianBlur in="SourceAlpha" stdDeviation="4"></feGaussianBlur> </filter> </defs> </svg> </body> ``` Box size correlates with the spread of the filter blur (`stdDeviation` value). Same effect seen using `feMorphology` with `operator="dilate"` — in that case the size of the spurious black box correlates with the assigned `radius`. If height style is removed from the div, causing the “Filter target” element to be visible on initial page load, the black square does not render (as expected). Observed in iOS 26.4.2 on iPhone 13 mini and iPad (9th gen) Not observed in Safari Version 26.4 (20624.1.16.18.2) on MacOS 15.7.5 (24G624) Curiously the square is only visible on iPhone in portrait orientation.
Attachments
testcase (1.53 KB, text/html)
2026-05-19 17:12 PDT, Karl Dubost
no flags
rendering in safari, firefox, chrome (233.07 KB, image/png)
2026-05-19 17:13 PDT, Karl Dubost
no flags
account+webkit-bugzilla@boermans.name
Comment 1 2026-05-19 03:31:10 PDT
Amendment: I wrote “Not observed in Safari Version 26.4 (20624.1.16.18.2) on MacOS 15.7.5 (24G624)” I have since reproduced in this version of Safari on MacOS, but *only* if the viewport height is taller than 515px. If the viewport is shorter the spurious black box is not rendered.
Simon Fraser (smfr)
Comment 2 2026-05-19 13:13:48 PDT
I have seen this too; it's something about our incorrect filter region logic when clipped.
Karl Dubost
Comment 3 2026-05-19 17:12:49 PDT
Created attachment 479726 [details] testcase
Karl Dubost
Comment 4 2026-05-19 17:13:38 PDT
Created attachment 479727 [details] rendering in safari, firefox, chrome notice the black square at the top right left in Safari. Not visible in Chrome and Firefox.
Karl Dubost
Comment 5 2026-05-19 18:06:27 PDT
Could it be in https://searchfox.org/wubkat/rev/d221d71a6a560cb45bb3e9b23e526b6bcfa9e4b3/Source/WebCore/rendering/RenderLayerFilters.cpp#178-179 ```cpp dirtyFilterRegion = intersection(filterBoxRect, dirtyFilterRegion); filterRegion = dirtyFilterRegion; ``` Before patch FILTER314999: entry filterBoxRect=(0.0,761.0 1059.0x69.0) dirtyRect=(0.0,512.0 1059.0x318.0) outsets={t=12 r=12 b=12 l=12} FILTER314999: after intersection dirtyFilterRegion=(0.0,761.0 1059.0x69.0) isEmpty=0 FILTER314999: after outsets expand filterRegion=(-12.0,749.0 1083.0x93.0) isEmpty=0 FILTER314999: PROCEED: building filter at filterRegion=(-12.0,749.0 1083.0x93.0) FILTER314999: entry filterBoxRect=(0.0,761.0 1059.0x69.0) dirtyRect=(0.0,0.0 1059.0x512.0) outsets={t=12 r=12 b=12 l=12} FILTER314999: after intersection dirtyFilterRegion=(0.0,0.0 0.0x0.0) isEmpty=1 FILTER314999: after outsets expand filterRegion=(-12.0,-12.0 24.0x24.0) isEmpty=0 FILTER314999: PROCEED: building filter at filterRegion=(-12.0,-12.0 24.0x24.0) Patch dirtyFilterRegion = intersection(filterBoxRect, dirtyFilterRegion); + if (dirtyFilterRegion.isEmpty()) + return nullptr; filterRegion = dirtyFilterRegion; After patch. Visually fixed. FILTER314999: entry filterBoxRect=(0.0,761.0 1059.0x69.0) dirtyRect=(0.0,0.0 1059.0x512.0) outsets={t=12 r=12 b=12 l=12} FILTER314999: after intersection dirtyFilterRegion=(0.0,0.0 0.0x0.0) isEmpty=1 FILTER314999: bail: dirtyFilterRegion empty after intersection — returning nullptr FILTER314999: entry filterBoxRect=(0.0,761.0 1059.0x69.0) dirtyRect=(0.0,512.0 1059.0x318.0) outsets={t=12 r=12 b=12 l=12} FILTER314999: after intersection dirtyFilterRegion=(0.0,761.0 1059.0x69.0) isEmpty=0 FILTER314999: after outsets expand filterRegion=(-12.0,749.0 1083.0x93.0) isEmpty=0 FILTER314999: PROCEED: building filter at filterRegion=(-12.0,749.0 1083.0x93.0) Tools/Scripts/run-webkit-tests --release imported/w3c/web-platform-tests/css/filter-effects/ css3/filters/ 541 tests ran as expected, 8 didn't: Expected to fail, but passed: (4) css3/filters/effect-opacity-hw.html imported/w3c/web-platform-tests/css/filter-effects/backdrop-filter-boundary.html imported/w3c/web-platform-tests/css/filter-effects/fecolormatrix-display-p3.html imported/w3c/web-platform-tests/css/filter-effects/filter-function/filter-function-linear-gradient.html Regressions: Unexpected image-only failures (1) imported/w3c/web-platform-tests/css/filter-effects/backdrop-filter-plus-filter-2.html [ ImageOnlyFailure ] Regressions: Unexpected missing results (1) imported/w3c/web-platform-tests/css/filter-effects/filter-target-offscreen-below-viewport-001.html [ Missing ] Regressions: Unexpected crashes (2) css3/filters/reference-filter-color-interpolation-update-layout.html [ Crash ] imported/w3c/web-platform-tests/css/filter-effects/svg-relative-urls-001.html [ Crash ]
Radar WebKit Bug Importer
Comment 6 2026-05-19 18:10:19 PDT
Note You need to log in before you can comment on or make changes to this bug.