Scalable Vector Graphics (SVG) have been a staple in Web Development for quite some time, and for a good reason. They can be scaled up or down without loss of quality due to their vector properties. They can be compressed and optimized due to the XML format. They can also be easily edited, styled, animated, and changed programmatically.
At the end of the day, SVG is a markup language. And just as we can use CSS and JavaScript to enhance our HTML, we can use them the same on SVGs. We could add character and flourishes to our graphic elements, add interactions, and shape truly delightful and memorable user experiences. This optional but crucial detail is often overlooked when building projects, so SVGs end up somewhat underutilized beyond their basic graphical use cases.
How can we even utilize SVGs beyond just using them statically in our projects?
Take the “The State of CSS 2021” landing page, for example. This SVG Logo has been beautifully designed and animated by Christopher Kirk-Nielsen. Although this logo would have looked alright just as a static image, it wouldn’t have had as much of an impact and drawn attention without this intricate animation.
Let’s go even further — SVG, HTML, CSS, and JavaScript can be combined and used to create delightful, interactive, and stunning projects. Check out Sarah Drasner’s incredible work. She has also written a book and has a video course on the topic.
Developers often feel discouraged to play around with SVG animations, either because of time constraints, or they believe that they need to master design, SVG markup, and one of many complex JavaScript-based animation libraries, or because of some other reason.
Even if you are completely unfamiliar with SVG markup, this quick 3-minute intro by Fireship is more than enough to get you up to speed.
Many impressive JavaScript-based animation libraries can be used to create stunning and complex SVG animations but in this article, we’ll stick to basics and showcase how few additional lines of CSS and JavaScript can make all the difference. Let’s make these seemingly advanced and often overlooked concepts accessible, so you can create delightful and meaningful SVG animations and interactions on the fly.
Meet Image Optimization, Addy Osmani’s brand new practical guide to optimizing and delivering high-quality images on the web. From formats and compression to delivery and maintenance: everything in one single 528-pages book.
SVG Workflow Tips
Before we dive into SVG animations, let’s go over some essential SVG tips and tricks. These should help you get a better grasp of SVG styling and ease you into the concepts of editing SVG markup, which we’ll rely on in later examples.
Utilizing CSS currentColor
For SVG Icons
Let’s start with a simple example. We have a monochromatic SVG of the star icon that we want to use in our button component.
<svg width="24" height="24" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="..." fill="#C2CCDE" />
</svg>
Let’s add it to our HTML and create a simple button component.
<button type="button">
<svg width="24" height="24" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="..." fill="#C2CCDE" /></svg>
Add to favorites
</button>
Our button already has some background and text color styles applied to it so let’s see what happens when we add our SVG star icon to it.
Our SVG icon has a fill
property applied to it, more specifically, a fill="#C2CCDE"
in SVG’s path
element. This icon could have come from the SVG library or even exported from a design file, so it makes sense for a color to be exported alongside other graphical properties.
SVG elements can be targeted by CSS like any HTML element, so developers usually reach for the CSS and override the fill
color.
.button svg * {
fill: var(--color-text);
}
However, this is not an ideal solution as this is a greedy selector, and overriding the fill
attribute on all elements can have unintended consequences, depending on the SVG markup. Also, fill
is not the only property that affects the element’s color.
Let’s showcase this downside by creating a new button and adding a Google logo icon. SVG markup is a bit more complex than our star icon, as it has multiple path
elements. SVG elements don’t have to be all visible, there are cases when we want to use them in different ways (as a clipping region, for example), but we won’t go into that. Just keep in mind that greedy selectors that target SVG elements and override their fill
properties can produce unexpected results.
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
<path d="..." fill="#4285F4" />
<path d="..." fill="#34A853" />
<path d="..." fill="#FBBC05" />
<path d="..." fill="#EA4335" />
<path d="..." fill="none" />
</svg>
We can look at the issue from a different perspective. Instead of looking for a silver bullet CSS solution, we can simply edit our SVG. We already know that the fill
property affects the SVG element’s color so let’s see what we can do to make our icons more customizable.
Let’s use a very underutilized CSS value: currentColor
. I’ve talked about this awesome value in one of my previous articles.
Often referred to as “the first CSS variable,”
currentColor
is a value equal to the element’scolor
property. It can be used to assign a value equal to the value of thecolor
property to any CSS property which accepts a color value. It forces a CSS property to inherit the value of thecolor
property.
We can simply use the CSS color
property to change SVG’s fill
property simply by assigning it the currentColor
value. This comes in very handy when SVG fill color needs to match text color and respond to various states, like hover and focus.
<!-- BEFORE -->
<path d="..." fill="#C2CCDE" />
<!-- AFTER-->
<path d="..." fill="currentColor" />
We can do the same for our Google logo. We need to make sure to avoid replacing the fill="none"
value as this element shouldn’t be visible.
<path d="..." fill="currentColor" />
<path d="..." fill="currentColor" />
<path d="..." fill="currentColor" />
<path d="..." fill="currentColor" />
<path d="..." fill="none" />
And we can safely remove our .button svg *
selector as our SVGs will respond to the CSS color
property value. Check out the following demo to see currentColor
in action, and feel free to play around and experiment with it.
By avoiding the override, we retain complete control over the icon styling. For example, if we needed to keep the original Google logo colors in the icon, we simply wouldn’t edit the SVG. If we decided to stick with the initial idea of overriding styles, we’d have to override the override to put the fill colors back or write a separate selector for that button, resulting in code duplication or unnecessarily increasing specificity.
If you are using Figma to create or export SVG icons, consider using a plugin to automatically replace all visible color values in an SVG with the currentColor
value. Here are a few Figma plugins that support this, alongside some other neat tricks for optimizing SVGs for the Web:
SVG Optimization
SVG elements can be optimized just like any other markup language — we can minify it and remove unnecessary formatting and metadata, we can remove unnecessary properties and invisible elements, and so on.
These optimizations can be done automatically, depending on your tech stack. SVGO is the most popular tool for optimizing SVGs and can be easily integrated with pretty much any tech stack. If you are looking for a handy web tool for quick manual optimization, Jake Archibald’s SVGOMG has been a go-to choice for many developers, including myself.
If you are looking for more, CSS-Tricks keeps a comprehensive list of various SVG optimization tools with plenty of information and articles on the topic.
Using SVGs With Popular JavaScript-Based Frameworks
Many popular JavaScript frameworks like React have fully integrated SVG in their toolchains to make the developer experience easier. In React, this could be as simple as importing the SVG as a component, and the toolkit would do all the heavy lifting optimizing it.
import React from 'react';
import {ReactComponent as ReactLogo} from './logo.svg';
const App = () => {
return (
<div className="App">
<ReactLogo />
</div>
);
}
export default App;
However, as Jason Miller and many other developers have noted, including the SVG markup in JSX bloats the JavaScript bundle and makes the SVG less performant as a result. Instead of just having the browser parse and render an SVG, with JSX, we have expensive extra steps added to the browser. Remember, JavaScript is the most expensive Web resource, and by injecting SVG markup into JSX, we’ve made SVG as expensive as well.
One solution would be to create SVG symbol objects and include them with SVG use. That way, we’ll be defining the SVG icon library in HTML, and we can instantiate it and customize it in React as much as we need to.
<!-- Definition -->
<svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<symbol id="myIcon" width="24" height="24" viewBox="0 0 24 24">
<!-- ... -->
</symbol>
<!-- ... -->
</svg>
<!-- Usage -->
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<use href="#myIcon" />
</svg>
Breathing Life Into SVGs
Animating SVGs can be easy and fun. It takes just a few minutes to create some simple and effective animations and interactions. If you are unsure which animation would be ideal for a graphic or should you animate it at all, it’s best to consult with the designer. You can even look for some similar examples and use cases on Dribble or other similar websites.
It’s also important to keep in mind that animations should be tasteful, add to the overall user experience, and serve some purpose (draw the user’s attention, for example).
We’ll cover various use cases that you might encounter on your projects. Let’s start with a really sweet example.
Animating A Cookie Banner
Some years ago, I was working on a project where a designer made an adorable cookie graphic for an unobtrusive cookie consent popup to make the element more prominent. This cookie graphic was whimsical and a bit different from the general design of the website.
I’ve created the element and added the graphic, but when looking at the page as a whole, it felt kind of lifeless, and it didn’t stand out as much as we thought it will. The user needed to accept cookies as the majority of website functionality depended on cookies. We wanted to create an unobtrusive banner that doesn’t block user navigation from the outset, so I decided to animate it to make it more prominent and add a bit of flourish and character.
I’ve decided to create three animations that’ll be applied to the cookie SVG:
- Quick and snappy rolling fade-in entry animation;
- Repeated wiggle animation with a good amount of delay in between;
- Repeating and subtle eye sparkle animation.
Here’s the final result of the element that we’ll be creating. We’ll cover each animation step by step.
Source link
Leave a Reply