Search code examples
google-chromefirefoxsvgsvg-filters

feComposite ignores feOffset result (except in Chrome)


I have a very simple SVG filter that produces totally different results in Chrome vs. Safari or Firefox (on Mac OS). The problem seems to center around using feComposite on an offset alpha channel. Here's my code:

<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="-1 -1 2 2">
  <defs>
    <filter id="foo">
      <feFlood flood-color="red" result="red-fill" />
      <feOffset dx="0" dy="0.1" in="SourceAlpha" out="offset-text" />
      <feComposite operator="in" in="red-fill" in2="offset-text" result="final" />
    </filter>
  </defs>
  <text font-size="1px" filter="url(#foo)">1</text>
</svg>

In Chrome I see a large red digit "1", while Safari and Firefox show only a blank white canvas. If I remove the <feOffset> and use SourceAlpha directly for compositing, like so:

<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="-1 -1 2 2">
  <defs>
    <filter id="foo">
      <feFlood flood-color="red" result="red-fill" />
      <feComposite operator="in" in="red-fill" in2="SourceAlpha" result="final" />
    </filter>
  </defs>
  <text font-size="1px" filter="url(#foo)">1</text>
</svg>

...then I see the red digit "1" in all three browsers, as expected.

Why couldn't I use the <feOffset> output in <feComposite>, and is there a recommended alternative?


Solution

  • This is a simple fix. That "out=" should be a "result=" in your filter. (And your font-size needs to be in a style declaration (Chrome is more forgiving of bad syntax.))

    <svg xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="-1 -1 2 2" >
    
    <filter id="foo">
      <feFlood flood-color="red" result="red-fill" />
      <feOffset dx="0" dy="0.1" in="SourceAlpha" result="offset-text" />
      <feComposite operator="in" in="red-fill" in2="offset-text" result="final" 
       />
     </filter>
     </defs>
     <text filter="url(#foo)" style="font-size:1px" >1</text>
     </svg>