CSS `filter: blur` generating dark borders
Bug report
Description / Observed Behavior
Using filter: blur on an element results in a dark border around the element's edges This is a common issue in rendering engines that include samples for the blur kernel outside the bounds of the stacking context, resulting in the edges being darker than intended.
This happens sometimes in normal HTML too, but there are tricks you can use to get around it (like rendering and then scaling up slightly or rendering into a larger bounding box). Unfortunately, none of these tricks seem to work with Satori (see my repro examples below).
imho this is a relatively important use case since blurring backgrounds for OG images is a pretty common technique.

Expected Behavior
Both the SVG and HTML outputs in the playground render correctly, but the PNG output images render incorrectly with dark borders.

Reproduction
- Playground example 1
- for this one, the filter should be applied first before the scale transform, but it doesn't appear to work that way in the PNG output
- Playground example 2
Note that for both of these, the SVG and HTML results render correctly, but the PNG output suffers from the dark border artifacts.
Additional Context
- repros with latest Satori (playground) as well as
@vercel/ogwith[email protected] - this may be a bug with resvg-js, though if anyone has a working workaround, I'd love to see it.
Thanks! 🙏
Likely related: https://github.com/RazrFalcon/resvg/issues/437
I'm wondering if we can work around this by rendering a larger scene and scale it down with transform: scale()?
I'm wondering if we can work around this by rendering a larger scene and scale it down with transform: scale()?
Hmmm in "userland", this doesn't work. See my first playground example above.
If Satori could do this at the library level, though, that'd be awesome. I'm just not sure if there could be unintended side effects for all of the use cases that don't use filters.
Maybe an additional top-level option to Satori / @vercel/og to increase the side of the canvas and then transform: scale()?
Oh you are right. I think this trick only works when the element is full-sized and can be cropped though...
@vercel/og to increase the side of the canvas and then transform: scale()