Needing a workaround for IE bug with SVG attribute filterUnits

816 views Asked by At

There seems to be a problem with the attribute "filterUnits" for SVG filters on IE 10+. This has effects for drop-shadow filters on (nearly) vertical or horizontal lines, see this example:

<svg height="500" width="500">
    <defs>
        <filter id="f1" filterUnits="userSpaceOnUse" width="300%" height="300%">
            <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5" />
            <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3" />
            <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
    </defs>
    <line x1="10" y1="205" x2="400" y2="200" 
        style="stroke:rgb(255,0,0); stroke-width:20" filter="url(#f1)" />
    <line x1="200" y1="50" x2="220" y2="300" 
        style="stroke:rgb(255,0,255);stroke-width:20" filter="url(#f1)" />
</svg>

This example works perfect in Chrome and Firefox, but the lines are partially clipped in IE 10, 11. It seems that the attribute value filterUnits="userSpaceOnUse"is not supported in IE. According to Microsoft (http://msdn.microsoft.com/en-us/library/ff934701%28v=vs.85%29.aspx and http://msdn.microsoft.com/en-us/library/ie/hh773402%28v=vs.85%29.aspx), filterUnits is not supported in IE9, but in IE10+.

Is there a workaround for this problem?

1

There are 1 answers

1
Michael Mullany On BEST ANSWER

IE11 seems to use a stroke width of 0 when calculating the filter region - regardless of how big your stroke is, AND it doesn't seem to support specifying the filter region in userSpaceUnits (even when you tell it to). This means that the filter region for a horizontal or vertical line is zero units for the y and x dimensions respectively.

A terrible terrible but effective hack is to draw a transparent shape with the filter dimension that you want along with your horizontal or vertical lines, and set the filter on a group element grouping that shape along with your desired shape.

This works in IE, Firefox, Chrome. (Isn't the web awesome!)

<svg x="0px" y="0px" height="500px" width="500px" viewbox="0 0 500 500">
    <defs>
        <filter id="f1" x="-200%" y="-200%" width="400%" height="800%">
            <feOffset result="offOut" in="SourceAlpha" dx="5" dy="5" />
            <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3" />
            <feComposite in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
    </defs>
    <line x1="10" y1="205" x2="400" y2="200" 
        style="stroke:rgb(255,0,0); stroke-width:20" filter="url(#f1)" />
    <line x1="200" y1="50" x2="220" y2="300" 
        style="stroke:rgb(255,0,255);stroke-width:20" filter="url(#f1)" />

  <g filter="url(#f1)">
  <line x1="10" y1="100" x2="400" y2="100" style="stroke:rgb(255,0,0);stroke-width:20"  />
    <line x1="10" y1="100" x2="400" y2="110" stroke="red" stroke-opacity="0" />
    <g>
</svg>

BTW this is not a bug - the spec doesn't require the stroke width to be taken into account when calculating the bounding box. IE doesn't, Firefox does.