Animating an Offset Value in SVG

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

In a lit¬≠tle exper¬≠i¬≠ment I‚Äôm work¬≠ing on I recent¬≠ly found a bit of a show-stop¬≠ping prob¬≠lem. After an APB on Twit¬≠ter I got a rapid reply which helped me solve it, but it seems that I may be the first per¬≠son to encounter this error, there¬≠fore it‚Äôs encum¬≠bent on me to doc¬≠u¬≠ment it. So this is that.

The Setup

I‚Äôve defined a radi¬≠al gra¬≠di¬≠ent with two col¬≠or stops. The first stop ele¬≠ment has an offset attribute with a val¬≠ue of 20% ‚ÄĒ val¬≠ues can be defined with a num¬≠ber (0 to 1) or a per¬≠cent¬≠age. The rel¬≠e¬≠vant markup looks like this (view the page source for the full code):

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

Next I’ve added an animate ele­ment inside the first stop, which tran­si­tions the val­ue of the offset attribute from 20% to 100%, over a dura­tion of one second:

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

This is how the result should appear:

The Problem

This ani¬≠ma¬≠tion works per¬≠fect¬≠ly in Fire¬≠fox, but not at all in Chrome or Safari (IE doesn‚Äôt sup¬≠port SVG ani¬≠ma¬≠tion, so this isn‚Äôt a con¬≠sid¬≠er¬≠a¬≠tion). But worse, the pres¬≠ence of the animate ele¬≠ment some¬≠how means the offset val¬≠ue of the stop par¬≠ent isn‚Äôt applied ‚ÄĒ so I get no ani¬≠ma¬≠tion, and no grace¬≠ful fallback.

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

The Solution

I have to thank Dirk Schulze of Adobe, co-edi­tor of the SVG2 spec, for this solu­tion. The prob­lem is due to a vague­ness in the SVG spec, and a dif­fer­ing inter­pre­ta­tion by brows­er ven­dors. The spec says the val­ue of the to attribute must match the attribute type, and the type is SVGAnimatedNumber, mean­ing strict­ly that only num­ber val­ues should be animated.

How¬≠ev¬≠er, as men¬≠tioned ear¬≠li¬≠er, per¬≠cent¬≠ages are a valid val¬≠ue type. So Fire¬≠fox have been more for¬≠giv¬≠ing in allow¬≠ing per¬≠cent¬≠age val¬≠ues to ani¬≠mate, while Chrome and Safari are stricter in only allow¬≠ing num¬≠ber val¬≠ues. There¬≠fore, the solu¬≠tion to the prob¬≠lem is to avoid per¬≠cent¬≠age val¬≠ues, as you see here:

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

The result is an ani¬≠ma¬≠tion which works cross-brows¬≠er, as you see here (if your brows¬≠er sup¬≠ports it):

The Fix

As both num­bers and per­cent­ages are valid val­ues for the offset attribute, it should be pos­si­ble to ani­mate them. My ide­al sit­u­a­tion would be that Chrome and Safari allow per­cent­ages to be ani­mat­ed, and the spec is updat­ed to make that clear­er. I’ll use this arti­cle as a bug report and see if some­thing can happen.

1 comment on
“Animating an Offset Value in SVG”

  1. [‚Ķ] Ani¬≠mat¬≠ing an Off¬≠set Val¬≠ue in SVG by Petey¬≠poo Gasston ‚Äď ‚ÄúThe prob¬≠lem is due to a vague¬≠ness in the SVG spec, and a dif¬≠fer¬≠ing inter¬≠pre¬≠ta¬≠tion by brows¬≠er vendors.‚ÄĚ [‚Ķ]