Animating an Offset Value in SVG

Warning This article was written over six months ago, and may contain outdated information.

In a little experiment I’m working on I recently found a bit of a show-stopping problem. After an APB on Twitter I got a rapid reply which helped me solve it, but it seems that I may be the first person to encounter this error, therefore it’s encumbent on me to document it. So this is that.

The Setup

I’ve defined a radial gradient with two color stops. The first stop element has an offset attribute with a value of 20% — values can be defined with a number (0 to 1) or a percentage. The relevant markup looks like this (view the page source for the full code):

<defs>
  <radialGradient id="rings">
    <stop class="stop1" offset="20%" />
    <stop class="stop2" />
  </radialGradient>
</defs>

Next I’ve added an animate element inside the first stop, which transitions the value of the offset attribute from 20% to 100%, over a duration of one second:

<stop class="stop1" offset="20%">
  <animate attributeName="offset" from="20%" to="100%" dur="1000ms" repeatCount="indefinite" />
</stop>

This is how the result should appear:

The Problem

This animation works perfectly in Firefox, but not at all in Chrome or Safari (IE doesn’t support SVG animation, so this isn’t a consideration). But worse, the presence of the animate element somehow means the offset value of the stop parent isn’t applied — so I get no animation, and no graceful fallback.

If you’re using Chrome or Safari, you can see the problem here (it will look fine in Firefox):

The Solution

I have to thank Dirk Schulze of Adobe, co-editor of the SVG2 spec, for this solution. The problem is due to a vagueness in the SVG spec, and a differing interpretation by browser vendors. The spec says the value of the to attribute must match the attribute type, and the type is SVGAnimatedNumber, meaning strictly that only number values should be animated.

However, as mentioned earlier, percentages are a valid value type. So Firefox have been more forgiving in allowing percentage values to animate, while Chrome and Safari are stricter in only allowing number values. Therefore, the solution to the problem is to avoid percentage values, as you see here:

<stop class="stop1" offset="0.2">
  <animate attributeName="offset" from="0.2" to="1" dur="1000ms" repeatCount="indefinite" />
</stop>

The result is an animation which works cross-browser, as you see here (if your browser supports it):

The Fix

As both numbers and percentages are valid values for the offset attribute, it should be possible to animate them. My ideal situation would be that Chrome and Safari allow percentages to be animated, and the spec is updated to make that clearer. I’ll use this article as a bug report and see if something can happen.

1 comment on
“Animating an Offset Value in SVG”

  1. […] Animating an Offset Value in SVG by Peteypoo Gasston – “The problem is due to a vagueness in the SVG spec, and a differing interpretation by browser vendors.” […]