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:
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.
Transform:translate
to move an objectLet'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:
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:
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;
}
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);
}
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:
ease
- specifies a transition effect with a slow start, then fast, then end slowly (this is default)linear
- specifies a transition effect with the same speed from start to endease-in
- specifies a transition effect with a slow start
ease-out
- specifies a transition effect with a slow end
ease-in-out
- specifies a transition effect with a slow start and end
cubic-bezier(n,n,n,n)
- lets you define your own values in a cubic-bezier function
#yellowCircle,
#pinkCircle,
#purpleCircle{
transition: all 3s ease-in-out;
}
#aquaRect,
#tealRect,
#blueLine{
transition: all 2s ease-out;
}