Animating SVG (CSS vs. GreenSock GSAP)

Inline SVGs (not those loaded as images) can be styled like any other collection of DOM elements. But there appear to be a few limitations. Primarily, due to the way transforms (coordinates) are handled within SVG relative positioning is hard.

I really wanted to explore animating SVG elements with purse CSS, and to an extent this went swimmingly… until I started trying to animate the SVGs child elements.

CSS animation on CodePen 

Screenshot of CSS animated SVG
Animated via CSS (CodePen)

As the coordinates inside an SVG are relative to the grouped elements inside the SVG definition (rather than the HTML DOM, or the window), when we start trying to position child elements I quickly hit a wall.


Defeated (for now) I picked up the oddly named GreenSock animation library (GSAP). It’s shockingly easy to get up and running. Once we have the GSAP library referenced in our code,

var myElementHandle = new
  document.getElementById("mySVGElement"), 160, 
    rotation: 360, transformOrigin:"center center", ease: Linear.easeNone, repeat:-1

GSAP animation on CodePen

Screenshot of SVG animated with GSAP
Animated via GSAP (CodePen)

Now we can target anything we want using names or class and GSAP will do the heavy lifting. A passive function of GSAP is how it handles changing animations (for example, triggering a new animation on mouseover on an element that is already animating). GSAP will blend any active animations to ensure a smooth interaction—something not possible in CSS.

As we’re relying on JS, it’s really easy for us to start manipulating our SVG in other ways too, such as generating new elements and handling interaction. For example, I added a couple of experimental functions:

// Creates a new svg element [id] attached to [parentID]
function createSVGElement(id, cssClass, x, y, parentID) {
  var svg = document.createElementNS("","circle");
  svg.setAttributeNS(null, "class", cssClass);

And this…

// Creates a clone of svg element [id] as [newID]
function cloneSVG(id, newID, x, y, parentID) {
  var node = document.getElementById(id);
  var newNode = node.cloneNode("true"); = newID;
  newNode.setAttributeNS(null, "cx", x);
  newNode.setAttributeNS(null, "cy", y);

Dev Notes

I’ve used SVG shapes generated from Sketch here, so had to make sure any elements / groups I wanted to target with JS had names. Sketch will slugify the names if you don’t add something JS-safe yourself.


Animated CSS reveal on page load

I’m still playing with animations on page load and put together a little demo and some notes.

What do we want to animate?

@keyframes fadeinanimation {
  from {
    opacity: 0;
  to {
    opacity: 1;

Now we can apply the animation to our elements (the .fadein class):

  .fadedin {
    opacity: 0;
    animation: fadeinanimation ease-in 1;
    animation-fill-mode: forwards;
    animation-duration: 1s;
    animation-delay: .2s;

See it in action:

Community site

With the migration to my new development server well under way, I was mulling over what to do with a place-holder page for the building I live in (because, buildings need sites too?)–then yesterday a notice board appeared in the shared hall. No excuses. So I replaced the site on the newly minted server with a hand-spun single page.

Features played with:

  • CSS animation on load
  • Google Maps API (+git source)

Screenshot of
Updated community placeholder site