When it comes to animating SVGs, there're three options: using CSS, JS, or SMIL. Each comes with its own pros and cons, whose discussion is beyond the scope of this article, but Sara Soueidan has a great article on the topic. In this post, I add a repeating shrink animation to a circle with all three methods, and then try to use these SVGs as favicons.
Animating SVG with CSS ⚓
Here's an example of animating an SVG with CSS based on the
animation
and the
transform
properties.
I scale the circle from the center and repeat the animation forever:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<style>
svg {
max-width: 100px;
}
circle {
display: block;
animation: 2s linear infinite both circle-animation;
transform-origin: 50% 50%;
}
@keyframes circle-animation {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
</style>
<circle fill="red" cx="50" cy="50" r="45"/>
</svg>
Animating SVG with JS ⚓
The SVG <script>
tag allows to add scripts to an SVG document.
It has some subtle differences
to the regular HTML <script>
, for example, it uses the href
instead of the src
attribute,
but above all it's important to know that any functions defined within any <script>
tag
have a global scope across the entire current document.
Below, you can see an SVG script used to reduce the radius of the circle until it's equal to zero,
then reset it to the initial value, and finally repeat this forever.
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle fill="blue" cx="50" cy="50" r="45" />
<script type="text/javascript"><![CDATA[
const circle = document.querySelector('circle');
let r = 45;
const animate = () => {
circle.setAttribute('r', r--);
if (r === 0) {
r = 45;
}
requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
]]></script>
</svg>
Animating SVG with SMIL ⚓
The last example uses SMIL, where, via the
<animate>
tag inside of the <circle>
tag, I declaratively describe that I want to
animate the circle's r
attribute (that determines the radius) and repeat it indefinitely.
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle fill="green" cx="50" cy="50" r="45">
<animate attributeName="r" from="45" to="0" dur="2s" repeatCount="indefinite"/>
</circle>
</svg>
Using Animated SVGs as Images ⚓
Before using animated SVGs as favicons, I want to briefly discuss
how you can use each of the three examples on a website.
Again there're three options: referenced via the src
attribute of an <img>
tag,
in an <iframe>
, or inlined in the main document.
Again, SVG scripts have access to the global scope, so they should definitely be used with care.
Some user agents, for example, Google Chrome, don't run scripts for SVGs in <img>
.
The Glitch embedded below shows all variants in action.
My recommendation would be to stick with CSS animations whenever you can,
since it's the most compatible and future-proof variant.
Using Animated SVGs as Favicons ⚓
Since crbug.com/294179 is fixed, Chrome finally supports SVG favicons,
alongside many other browsers.
I have recently successfully experimented with
prefers-color-scheme
in SVG favicons,
so I wanted to see if animated SVGs work, too.
Long story short, it seems only Firefox supports them at the time of writing,
and only favicons that are animated with either CSS or JS.
You can see this working in Firefox in the screencast embedded below.
If you open my Glitch demo in a standalone window,
you can test this yourself with the radio buttons at the top.
Should you use this in practice?
Probably not, since it can be really distracting.
It might be useful as a progressive enhancement to show activity during a short period of time,
for example, while a web application is busy with processing data.
Before considering to use this, I would definitely recommend taking the user's
prefers-reduced-motion
preferences into account.
This post appeared first on https://blog.tomayac.com/2019/12/01/animated-svg-favicons/.