Bring your SVG to Life - SVG/CSS Transitions Tutorial

Step 1: Create your SVG

You can use a free graphic design tool such as Figma to draw your icon and export it as SVG, or you can code your SVG by hand. Whichever method you use to create your vector graphic, be sure that each element of your SVG is labeled clearly with a self-descriptive and unique @id.

Paste your SVG code into a new HTML document. Create a CSS file and associate it in the head of your HTML.

In this tutorial, we will be using the following SVG code to manipulate the movement and color of two circles on mouse hover:

           
            
            <svg width="350" height="300" viewBox="0 0 115 115" fill="none" xmlns="http://www.w3.org/2000/svg">
                 <circle id="yellowCircle" cx="57.5" cy="57.5" r="50" fill="yellow"/>  
                 <rect id="aquaRect" x="5" y="10" rx="10" ry="10" width="70" height="25" stroke-width="6" fill="transparent" stroke="#00CFFF"/>
                 <rect id="tealRect" x="50" y="20" rx="10" ry="10" width="60" height="70" stroke-width="5" fill="transparent" stroke="#5adbab"/>  
                <path id="blueLine" d="M10,63 Q40,85 60,60 T105,63" stroke-width="5" fill="transparent" stroke="blue"/>
                 <ellipse id="pinkCircle" cx="35" cy="78" rx="20" ry="25" stroke-width="3" fill="transparent" stroke="pink"/>
                <circle id="purpleCircle" cx="91.5" cy="90" r="20" fill="purple"/>
           </svg>
            
           
       

Which should render in your browser looking something like this:

Step 2: CSS Manipulations and Variables

In your CSS, create a style rule for the :root pseudo-class of your HTML document. The :root applies to the root of your HTML document, and since all style expressions written here will apply to the entire document, it is a good place to store your CSS Variables.

We will want to create variables for all of the SVG object properties you will use in your SVG elements to make it easier to remember and reference them as you animate.

Let's create variables for the colors of our shapes:

           
               :root{
                -yellow: #FF0;
                --aqua: #00CFFF;
                --blue: #00F;
               --pink: #ffc0cb;
               --purple: #800080;
               --teal: #5adbab;
               --transparent: #5adbab00;           
               }
           
       

Since we now have variables declaring our shape colors, we no longer need the @fill attributes in our SVG circles. Delete the fill from our SVG, and write CSS rules declaring the fill for each of our shapes using our CSS variables:

               
            #yellowCircle{
             fill:var(--yellow)
            }

            #aquaRect{
             stroke:var(--aqua);
             fill:var(--transparent);
            }

            #tealRect{
             stroke:var(--teal);
            fill: var(--transparent);
            }

             #blueLine{
                 fill:none;
                stroke:var(--blue)
            }


            #pinkCircle{
             stroke:var(--pink);
            fill:var(--transparent);
            }

            #purpleCircle{
               fill:var(--purple)
            }
           
       

Now, you'll want to create a CSS rule that applies a smooth transition over every element within your SVG that you want to animate. You don't have to animate every singe shape in your SVG (in fact, we encourage you not to! Simplicity and subtleness are key!) For this example though, we will be animating all five of our circles.

To do this, we need to utilize the transition CSS property:

           
            #yellowCircle,
            #aquaRect,
             #tealRect,
            #blueLine,
            #pinkCircle,
            #purpleCircle{
                 transition: all 1s ease;
            }
           
       

We encourage you to mess with the values of the transition property to tweak how your SVG transitions between animation points to your liking! But we won't see any of the animation until we apply :hover style rules in our CSS.

Animation CSS

Transform:translate to move an object

Let's try getting two of our SVG objects to move their positions when the mouse overs over the SVG.

To do this, we will utilize the CSS pseudo-property :hover on our root SVG element, and then apply a new CSS rule for the objects we wish to move.

To move an object's position, we will use transform:translate(x, y)

It's good practice to adjust the X and Y positions by % instead of pixel (px) units, because it's easier to adjust and it stays relative to the original position.

    
        svg:hover #purpleCircle{
         transform:translate(-50%, -10%)
        }

        svg:hover #pinkCircle{
            transform:translate(40%, -40%)
        }
    

This CSS code should make your objects move upon mouse over:

Changing Colors

Using the same svg:hover method we used to animate position changes, we can also change fill and stroke colors of our objects.

        
            svg:hover #yellowCircle{
                fill:var(--teal)
            }
            svg:hover #aquaRect{
                stroke:var(--yellow)
            }   
            svg:hover #tealRect{
                stroke:var(--aqua);
                fill:var(--purple);
            }
        
    

Your result should look something like this:

Scaling objects with transform:scale()

Lets try animating a change in size of two of our objects. We can animate multiple properties of the same object within the same CSS rule.

One limitation you will encounter is if you apply two different transform: changes on the same SVG object. The second transform: rule will cancel out the first. Try it yourself to see it.

            
                svg:hover #pinkCircle{
                    transform:translate(40%, -40%);
                    transform:scale(140%);
                }
            
        

The pink circle will now scale, but it will no longer move positions.

To compromise, try scaling objects who do not already have a tranform: property applied to them.

            
                svg:hover #aquaRect{
                    stroke:var(--yellow);
                    transform:scale(150%);
                }
                svg:hover #yellowCircle{
                    fill:var(--teal);
                    transform:scale(110%);
                }
                svg:hover #tealRect{
                    stroke:var(--aqua);
                    fill:var(--purple);
                    transform:scale(75%);
                }
            
        

Notice how the objects will only scale from the top left corner of the object. To make the objects scale from the center, we will use the transform-origin property:

            
                svg:hover #yellowCircle{
                    fill:var(--teal);
                    transform:scale(110%);
                    transform-origin:center;
                }
                svg:hover #tealRect{
                    stroke:var(--aqua);
                    fill:var(--purple);
                    transform:scale(75%);
                    transform-origin:center;
                }
            
        

Rotating objects with transform:rotate()

The same rules that applied to our transform:scale() and transform:translate() to animate our objects will also apply to rotation - except that instead of using % as our units, we will be using deg to set the degree of rotation.

Let's try rotating a few of our objects.

                
                    svg:hover #aquaRect{
                        stroke:var(--yellow);
                        transform:rotate(360deg);
                        transform-origin:center;
                    }
                    svg:hover #blueLine{
                        transform:rotate(-180deg);
                    }
                
            

We can change the transform:origin value to alter from what side of the object it will rotate.

                
                    svg:hover #aquaRect{
                        stroke:var(--yellow);
                        transform:rotate(360deg);
                        transform-origin:right;
                    }
                    svg:hover #blueLine{
                        transform-origin:center;
                        transform:rotate(-180deg);
                    }
                
            

Now make it your own!

All of these animation properties can be adjusted to your liking! Sometime's it's fun to see how the animation looks when it is slowed down in the transition: property.

You can also change the type of ease mechanism your animation uses.

Here is a handy list of all the different types of transition properties you can apply to your animation style:

    
        #yellowCircle,
        #pinkCircle,
        #purpleCircle{
             transition: all 3s ease-in-out;
        }
        #aquaRect,
        #tealRect,
       #blueLine{
           transition: all 2s ease-out;
       }