satori icon indicating copy to clipboard operation
satori copied to clipboard

CSS `filter: blur` generating dark borders

Open transitive-bullshit opened this issue 3 years ago • 5 comments

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.

og-example-css-filter-blur-borders

Expected Behavior

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

CleanShot 2022-11-14 at 22 04 41@2x-opt

Reproduction

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/og with [email protected]
  • this may be a bug with resvg-js, though if anyone has a working workaround, I'd love to see it.

Thanks! 🙏

transitive-bullshit avatar Nov 15 '22 04:11 transitive-bullshit

Likely related: https://github.com/RazrFalcon/resvg/issues/437

transitive-bullshit avatar Nov 15 '22 04:11 transitive-bullshit

I'm wondering if we can work around this by rendering a larger scene and scale it down with transform: scale()?

shuding avatar Nov 23 '22 19:11 shuding

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()?

transitive-bullshit avatar Nov 23 '22 20:11 transitive-bullshit

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()

shuding avatar Nov 28 '22 18:11 shuding