Resizing SVG Circle Radius Using CSS Animation

I'm trying to animate an SVG circle's radius attribute with CSS. Whilst (using the Firefox Inspect Element tool) I can see that the animation itself is setup and running correctly, the size of the ".innerCircle" doesn't visibly change.

If you can spot anything that I've obviously missed, or help in any way I'd be greatly appreciative. I'm rather new to this, so if I have gone about this wrong, please be kind!

I've pasted my files underneath for reference.

Thanks again.

@keyframes buttonTransition { from { r: 5%; } to { r: 25%; }
}
.innerCircle { animation-duration: 1s; animation-iteration-count: infinite; animation-name: buttonTransition;
}
<html> <head> <link href = "styling.css" rel = "stylesheet" type = "text/css"></link> </head> <body> <svg class = "button" expanded = "true" height = "100px" width = "100px"> <circle cx = "50%" cy = "50%" r = "35%" stroke = "#000000" stroke-width = "10%" fill = "none"/> <circle class = "innerCircle" cx = "50%" cy = "50%" r = "25%" fill = "#000000"/> </svg> </body>
</html>

4 Answers

In SVG 1.1 the radius of a circle was an attribute and not a CSS property. SVG 2 changes this and instead makes the circle's radius a CSS property that's mapped to an attribute.

CSS animations animate CSS properties and do not animate attributes.

Firefox has now implemented this part of the SVG 2 specification so the testcase in the question will work now although it didn't when the question was written.

SMIL animations will work on attributes (and CSS properties).

<html> <head> <link href = "styling.css" rel = "stylesheet" type = "text/css"></link> </head> <body> <svg class = "button" expanded = "true" height = "100px" width = "100px"> <circle cx = "50%" cy = "50%" r = "35%" stroke = "#000000" stroke-width = "10%" fill = "none"/> <circle class = "innerCircle" cx = "50%" cy = "50%" r = "25%" fill = "#000000"> <animate attributeName="r" begin="0s" dur="1s" repeatCount="indefinite" from="5%" to="25%"/> </circle> </svg> </body>
</html>
5

There is a simple alternative: animate element scale instead of circle radius. As of 2018, it is supported in Edge and all modern browsers.

SMIL animations is deprecated and only supported by browsers for legacy reasons. It may be dropped in the future and will never appear in Edge or some future browsers.

@keyframes buttonTransition { from { transform: scale(0.2); } to { transform: scale(1); }
}
.innerCircle { animation-duration: 1s; animation-iteration-count: infinite; animation-name: buttonTransition; transform-origin: center center;
}
<html> <head> <link href = "styling.css" rel = "stylesheet" type = "text/css"></link> </head> <body> <svg class = "button" expanded = "true" height = "100px" width = "100px"> <circle cx = "50%" cy = "50%" r = "35%" stroke = "#000000" stroke-width = "10%" fill = "none"/> <circle class = "innerCircle" cx = "50%" cy = "50%" r = "25%" fill = "#000000"/> </svg> </body>
</html>
7

If anyone is still looking into how to do this I found a pretty good solution for a filled circle without using SMIL. This solution is a bit of a hack, and it will only work for circles that have a solid fill in them. Essentially what I did was animate the stroke width of these circles to appear as if they are growing.

My original circle

<circle cx="46" cy="46" r="2.8"/>

For this to work I set the radius of the circle to be close to be close to 0.

<circle cx="46" cy="46" r="0.01"/>

Then set a stroke width to be twice the amount of the original radius, and finally setup the animation of the stroke width.

@keyframes circle_animation { from { stroke-width: 0; }
}
circle { stroke-width: 5.6; animation: circle_animation .5s linear infinite;
}

OP query now works out of the box since some browser versions and SVG2 support.

Starting with SVG2, cx, cy, and r are Geometry Properties, meaning those attributes can also be used as CSS properties for that element.


This is the same demo defining all the geometry from css. The same cascading rules apply, if a html attributes is declared, it will override stylings from the style attributes, and if a rule is declared in the style attribute, it then override the class rules.

@keyframes buttonTransition { from { r: 5%; } to { r: 25%; }
}
.button { width: 30%; height: auto
}
.outterCircle { cx: 50%; cy: 50%; r: 35%; stroke: #000000; stroke-width: 10%; fill: none
}
.innerCircle { cx: 50%; cy: 50%; r: 25%; fill: #000000; animation-duration: 1s; animation-iteration-count: infinite; animation-name: buttonTransition
}
<svg> <circle/> <circle/>
</svg>

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like