Fun (and useful) SVG Animation With CSS
Web Directions Respond 2017
by Brett Snaidero
@brettsnaidero : Twitter | @brettsnaidero : Codepen
Hi everyone, my name is Brett Snaidero.
I'm really excited because I'm going to be talking to you a bit about something that I am really passionate about, which is SVG.
But before we dig into it...
Interactive Designer at Internetrix
Primarily work as a web designer — graphic design and front end
Design background
Quite fond of HTML & CSS
Background:
I work at Internetrix, a digital agency based in Wollongong, as an Interactive Designer.
I come from a graphic design background, that's what I studied at University, but I also love HTML and CSS -
I'm obsessed with the process of writing markup, and the possibilities open to us as designers and developers.
It makes sense that I'm a huge fan of SVG, as it kind of marries my knowledge of programs like Photoshop and Sketch, with the world of markup -
they're a declarative way to 'write' graphics.
What we'll cover
What is SVG?
Inline SVG
SVG elements and attributes
Styling SVG with CSS
Stroke/Line animation
Some fun examples
So what are we going to cover today?
I'm going to give you a quick intro on SVG, then we're going to chat about how we can embed SVG in our webpages, and how we can style them with CSS.
Then we'll go over one way we can animate SVG elements, and I have a some quick tutorials and a few cool examples to show you.
SVG: Scalable Vector Graphics
Graphics file format — .svg
Resolution independent
Created with programs like Illustrator and Sketch
May contain vector graphic shapes, bitmap (raster) images and text
I'm sure many of you are using SVG in your projects - hands up if you've used SVG before?
They're great right? I'm not going to try to evangelise SVG too much, because I'm competitive and I don't really need you all to be making cooler stuff than me... but they can be an incredibly useful addition to your front-end toolkit, and if you're reluctant to use them, I think I'm going to try and convince you that they're really useful and really easy.
Rather than talking about complex animation, today I want to focus on the kind of humdrum things we do in every project, and how SVG with a dash of CSS can liven them up and open up some new possibilities for us as designers and developers.
------
Just a quick intro for those of you who aren't super familiar with SVG - it is a file format - specifically it is a vector graphics format (vector meaning resolution independent) which can be created in any respectable vector graphics editing program (Illustrator / Sketch).
SVG Text
SVG <svg viewbox ="0 0 200 100" >
<rect x ="75" y ="10" width ="60" height ="45" fill ="orange" />
<circle cx ="30" cy ="55" r ="30" fill ="blue" />
<text x ="100" y ="85" font-size ="20" fill ="white" >
SVG Text
</text >
</svg >
So this is an SVG, being rendered in the browser.
If you compare the markup to the rendering, it's pretty easy to get a basic grip on what the markup is doing - like here we have the rectangle element, with some attributes defining it's size, position and colour - and up top we can see that rectangle.
SVG and HTML: Long lost siblings
SVG is made up of tags, just like HTML, which define the 'structure' of the document.
HTML Tags
HTML <body >
<div >
<header >
<footer >
<h1 >
<p >
<section >
<article >
SVG Tags
SVG <circle />
<ellipse />
<line />
<polygon />
<polyline />
<rect />
<path />
<text />
You can read an SVG file just like you can read the markup in a HTML page - each tag defines an element, and each tag can have attributes providing more information about the element.
Most of the tag names's in SVG are a specific type of shape or path. So a makes a circle appear, an makes a fancy circle appear, a is a straight line between 2 points, and so on.
------
Of all these vector shape and line elements, the element is kind of the grandmother, in that it can be used to create each of the other elements - circles, irregular shapes, curves -
but the syntax is fairly complicated, whereas the other elements offer us a simplified syntax which we can usually read and edit quite easily.
Embedding SVG 'inline' in HTML
We can put the SVG markup directly into our website as an HTML element, and it will render.
HTML <body >
<div > Your SVG can sit in your HTML!</div >
<svg viewbox ="0 0 200 100" width ="200" height ="100" >
<rect x ="75" y ="10" width ="60" height ="45" fill ="orange" />
<circle cx ="30" cy ="55" r ="30" fill ="blue" />
<text x ="100" y ="85" font-size ="20" fill ="white" > SVG Text</text >
</svg >
</body >
There are actually seven ways to embed SVG on a webpage, but I'm just going to be talking about what I would say is the simplest way to include SVG on your website, which is by embedding the SVG code directly in the HTML, or 'inline SVG'.
For those of you who are fairly new to SVG, this might blow your mind, but you can just drop the markup for an SVG graphic into your HTML page, and it will display!
SVG Text
OPEN INSPECTOR ---
And this also gives us complete access to the elements inside the graphic - you can interact with the elements using Javascript and CSS, with very few limitations. If you open up your browser's inspector you're going to see that all the tags are accessible in the DOM, available for us to play with.
The viewBox
attribute defines a grid
SVG <svg viewBox ="0 0 10 10" >
</svg >
SVG can look daunting, if you're looking at the code that's being exported by Illustrator, but it's surprisingly simple to kind of draw things if you write it yourself.
The 'viewbox' attribute is really all you need on an inlined tag, and this defines the grid to be used by the graphic.
So the first 2 numbers we can ignore for now, but the last 2 are the grid's X and Y values - so if we put 10 10 here, it gives us a 10x10 grid to work with.
And then we can draw elements according to that grid
2,5
8,5
SVG <svg viewBox ="0 0 10 10" >
<line x1 ="2" y1 ="5" x2 ="8" y2 ="5" />
<polyline points ="5,2 8,5 5,8" />
</svg >
And the syntax for most SVG elements is really easy to read and write. For example, the polyline element is just a series of grid coordinates, which draws a line between each of these points.
So it can be easy for us to draw simple elements, without ever opening a graphics program. I find it really useful to have the ability to draw triangles and arrows without having to leave the HTML/CSS for the page I'm working on.
We can write our SVG, or we could just use a program to generate our SVG
Of course, for more complicated shapes, there are various programs and tools for generating SVG - designers in the audience might be familiar with exporting as SVG from Illustrator or Sketch.
We can open the exported file in a text editor to simply copy and paste the markup across.
SVG Optimisation Tools
Minimise size and improve readability
Remove unneccessary tags
Simplify paths
Clean up attributes
The only issue with this is that these exported SVG's often aren't optimised for Inline SVG purposes -
so they'll have a lot of attributes which we don't need, and the markup won't be optimised for reading.
If you decide to start using SVG more, I would recommend looking into optimisation tools, which can help you to minimise the file size and improve readability.
We can apply CSS to SVG elements
HTML <svg viewBox ="0 0 200 200" >
<path class ="star" d ="..." />
</svg >
CSS svg .star {
fill : rgba (0 ,0 ,0 ,0.1 );
stroke : #FFF ;
stroke-width : 5px ;
stroke-linecap : round;
}
SVG Styling Properties Documentation
With Inline SVG, because you are putting the graphic with all it's elements directly into your HTML, you can use CSS to style these individual elements,
just like you would a regular HTML element. So you can target elements by the tag name, or put classes and ids on them and target those - whatever you like.
Now before you get too excited, there are limits to what CSS can be applied to SVG elements -
so for example, we can't just put a background image on this circle using CSS. An important exception is animation and transition properties,
which we can define on SVG elements...
CSS Animations work on SVG elements too!
SVG svg .star {
animation : rotate 10s infinite linear;
}
@keyframes rotate {
0% { transform : rotate (0deg ); }
100% { transform : rotate (360deg ); }
}
...which opens up the possibility of animating each element of our graphic. You can see how I've put an animation on this star that uses transform to spin it around.
When I say that some CSS properties won't work on SVG, SVG has a bunch of it's own styling properties, which can be set using CSS.
Instead of using something like color, to set the fill color of an SVG element we use 'fill', appropriately enough. Likewise, instead of using border or outline,
we set the 'stroke'.
In this example, you can see I've been able to set the style of the star using CSS.
SVG Paths + Stroke + CSS Animation =
Line Animation
To give you a taste of what you can do by mixing CSS and SVG, I thought I'd start with an example of a certain flavour of SVG animation which is quite simple,
and I'd say can be really useful - and that is line animation.
Polygon Console Review Illustrations
This is a technique which has been fairly popular recently - if you've seen any of these animations where a lined illustration is kind of 'drawn' onto the page,
then it's likely that SVG was behind the scenes. I think the technique was (maybe) first popularised by these illustrations done by Polygon.com
stroke
The color of the stroke.
blue
stroke-width
The width of the stroke.
3px
stroke-dasharray
Define a series of strokes (eg. dashes, dots).
10px 20px
stroke-dashoffset
Offset the beginning of the stroke.
20px
stroke-linecap
The shape used to cap the stroke/s.
round
stroke-linejoin
The shape used to join two lines.
bevel
So I mentioned you can style the stroke on an SVG element - you actually have a bunch of properties that control this:
Animating lines with stroke-dasharray
+ stroke-dashoffset
.line {
stroke-dasharray: ;
stroke-dashoffset: 0.00 ;
}
The way line animations have been created is really quite simple.
We can use stroke-dasharray to create a stroke which is the length of the path,
and then use stroke-dashoffset to push that line along the path until it is hidden.
To do this, all we need to know is the length of the path.
Need help finding the line length?
You can find the exact length of an SVG path using a little bit of Javascript - with the getTotalLength method
JS let path = document .querySelector('.star' );
let length = path.getTotalLength();
You might be wondering how we know how long the path is - I think it's probably important that I point out that svg is
a little quirky in that it uses it's internal grid system as the basis for it's sizing units - so 1 CSS pixel doesn't neccessarily equal 1 pixel in the SVG.
We can do this kind of manually, like I just did, just using the inspector to figure out the length of the path.
Or, if we want to be exact, and you're not avoiding Javascript, we can use the 'getTotalLength' method in Javascript to find the length.
Then , we can transition the stroke-dashoffset
so the line is drawn back onto the path.
CSS .star {
stroke-dasharray : 390px ;
animation : draw 5s linear infinite;
}
@keyframes draw {
0% {
stroke-dashoffset : 390px ;
}
100% {
stroke-dashoffset : 0px ;
}
}
Remember, we can use CSS transitions and animations, so we can animate this, creating the drawing effect we're looking for.
By bringing the dashoffset back to zero, we get the dash 'drawn' back onto the path, achieving that effect we're looking for.
Line animation is a useful technique for animated graphics
But SVG line animation can be a very useful technique for easily adding style to common website elements
This technique isn't limited to creating those 'drawing' animations, it's just generally a useful technique for animation -
these are both graphics which make use of line drawing method that aren't that 'drawing' style.
If you're thinking, "Okay, so I can use SVG and CSS to do animation, but I'm not creating banners or graphics day to day",
I think that having this tool in your front end skillset can give you a really useful new way to implement your kind of 'day to day' ux solutions too.
Tutorial Time #1
Making an Animated Hamburger Menu Icon with SVG + CSS
As an example, I'd like to show you how I can make an animated hamburger icon,
using those same principles. So this is what we're going to be making, fairly simple - but something which you might not be able to do with just HTML and CSS.
We start by creating the 'rails' on which our lines will travel.
To get started, I've made this graphic in Illustrator
It might look a little confuzzling at first, but what this is is the 'rails' on which the lines travel - throughout the animation.
There are three lines - which make both the shapes we need in this icon animation.
So if we break it down to the individual paths, you can see that the first 2 form the cross, and then loop around to also form the top and bottom of the hamburger icon.
And the last line just forms the middle bar of the hamburger icon.
We then define the stroke-dasharray
and stroke-dashoffset
to create the hamburger icon.
CSS .top , .bottom {
stroke-dasharray : 50px 600px ;
stroke-dashoffset : 0px ;
}
.middle {
stroke-dasharray : 50px 60px ;
stroke-dashoffset : 0px ;
}
Then, we work out the 'active' state, where the lines form the cross.
CSS .active .top ,
.active .bottom {
stroke-dasharray : 70.71px 600px ;
stroke-dashoffset : -392px ;
}
.active .middle {
stroke-dashoffset : 51px ;
}
So, using CSS and what we've just learnt about SVG stroke, it is possible to manipulate the stroke on those paths so it will only display the 'segments' of the path which make up the hamburger icon.
We use stroke-dasharray to set the size of the dash, and stroke-dashoffset to move where that dash appears on the path.
If you're wondering how I found those values, I just used the inspector to manually tweak the values until I found the right numbers.
All we need to do is figure out the 'state' that we're going to transition to - the cross icon.
So again, we play with the stroke-dasharray and stroke-dashoffset settings to create the cross, and to hide the hamburger.
CSS
.line .top {
transition : 0.5s stroke-dasharray ease 0s , 0.5s stroke-dashoffset ease 0s ; }
.line .bottom {
transition : 0.5s stroke-dasharray ease 0.25s , 0.5s stroke-dashoffset ease 0.25s ; }
.line .middle {
transition : 0.25s stroke-dasharray ease 0.25s , 0.25s stroke-dashoffset ease 0.25s ; }
.active .line .middle {
transition : 0.25s stroke-dasharray ease 0s , 0.25s stroke-dashoffset ease 0s ; }
Then, those two states: hamburger and cross - can be animated between using a simple class toggle.
I've changed the timing to dictate the speed and timing of the transitions, so that the transition looks more fun (?).
Other Styles
Codrops Hamburger Icon Tutorial
Now this is a fairly tame example of this, Codrops (Luis Manuel) has another cool example that's built on the same technique,
they use a Javascript library to handle all these things I've just shown you, so if you feel like a bit more of a deep dive, definitely go check that out.
Button
So that's a somewhat complicated example, but you can use the same principles to do really simple stuff too
So this button hover effect is built on the same principles, and accomplishes an effect which would be quite difficult to replicate with just HTML and CSS
Tutorial Time #2
Checkbox/Radio Buttons
Another common UX implementation that designers and developers are dealing with in almost every project is checkboxes and radio buttons.
This is a perfect place for us to use SVG to jazz up these kind of common patterns in a really easy way. So we'll look at creating...
...these 'hand drawn' checkbox and radio buttons. Kind of cool right?
Again we're animating SVG stroke to get a 'drawn' effect, but this time we're going for that hand-drawn effect.
Our Shapes
Just like when you use CSS to create a custom input, the basic idea is to visually hide the input elements, use a psuedo-element to recreate the input box or circle, and then use an SVG path to 'draw' in the selection illustration.
This part uses exactly the same principles as the hamburger menu we just made, just using CSS to animate those stroke properties to create this effect.
We'll use these shapes that have been created in Illustrator for our hand-drawn selections illustrations.
Our HTML
HTML <input name ="tick" type ="checkbox" >
<label for ="tick" >
Legit hand-drawn checkbox tick
<svg viewBox ="0 0 100 100" >
<path d ="M22.3,61.3c5.7,4.1,13.2,11.8,16.7,18
C53,60.5,66,41,77.7,20.8" />
</svg >
</label >
HTML-wise, for this we just need to place our SVG inside the label element, which itself goes directly after the checkbox input.
Visually hide the input and create a fake check box in it's place
CSS
input [type="checkbox"] {
opacity : 0 ;
-webkit-appearance : none;
display : inline-block;
vertical-align : middle;
z-index : 100 ;
width : 50px ;
height : 50px ;
top : 50% ;
left : 0 ;
margin-top : -25px ;
position : absolute;
}
CSS
label :before {
content : '' ;
border : 4px solid #5296ab ;
transition : opacity 0.3s ;
width : 50px ;
height : 50px ;
top : 50% ;
left : 0 ;
margin-top : -25px ;
position : absolute;
cursor : pointer;
}
Then we can visually hide the input and create a fake input box or circle in it's place using a psuedo element....
CSS
input [type="checkbox"] + label svg {
stroke : orange;
stroke-width : 1px ;
stroke-linecap : round;
stroke-dasharray : 100px 200px ;
stroke-dashoffset : 100px ;
transition : stroke-dashoffset 0.2s ease-in-out 0s ;
}
input [type="checkbox"] :checked + label svg {
stroke-dashoffset : 0px ;
}
... and then position our SVG over this fake input. Then, we can use the :checked selector to toggle our stroke on the SVG path, when the input is checked.
SVG are fantastic 💖
Scalable
Great browser support
Accessible
Small file size
I'm hoping that I've managed to show you how SVG complements HTML and CSS really well - I like to think that it 'fills in the gaps' alot of the time when I'm working,
especially when doing responsive stuff - because they're completely scalable, they mesh with browser rendering of HTML/CSS in a way which is hard to accomplish with other types of graphics. (Raster Graphics, Canvas)
Know your Javascript?
There are a number of JS animation libraries which give you control over SVG animation:
If you just know HTML and CSS, hopefully those examples have shown that you don't really need to know JS to do SVG animation - plain old CSS can get you far.
However, there are a whole bunch of JS libraries out there that can help you with SVG animation, and if you know Javascript, I'd recommend giving one a go.
Advantages of using a JS library
Support IE and older browsers
Simplify chaining animations
Programmatic animation
Tweening and shape animation
Removes manual 'hard-coding' of values
Why? Because they can help you to focus on the animations you want to achieve - and spend less time worrying about things like 'how long is this path', or will this look the same in other browsers.
Some of these libraries also let you do things like shape morphing/tweening, for even more intense animation stuff.
Example: JS animation with Velocity
Run Animation
JS $("#rect" ).delay(500 )
.velocity({ x: "+=160" , y: "25%" })
.velocity({ fill: "#0d7ea1" , strokeWidth: 3 })
.velocity({ height: 80 , width: 80 })
.velocity({ rotateZ: 90 , scaleX: 0.5 })
.velocity("reverse" , { delay: 250 });
To give you a quick example of how most of these libraries work, this is an example that uses the Velocity plugin
So here I've selected my SVG element, the rectangle, and then you can kind of define a 'timeline' by chaining methods,
as in this little example I grabbed off the Velocity website.
Animating SVG can be fun and useful! 😎
Thinking of SVG as an extension of HTML allows you to accomplish more in the browser.
Easy to read and understand
Easy to style and animate
They give your HTML/CSS superpowers!
I hope you got something out of this talk, if you haven't played too much with SVG, I hope you go away and have a bit of a play
So I hope you agree with me when I say - "If you know HTML, SVG is easy to learn", the markup is very familiar to HTML, and alot of the same 'rules'.
"Styling inline SVG with CSS is easy", again, if you know how to style HTML with CSS, then you're halfway there to doing the same with SVG
"Animating SVG with CSS lets you do lots of cool things", so SVG really opens the lid on a whole new world of possibilities, in terms of design and animation
"SVG gives your HTML/CSS superpowers", and generally, knowing SVG is a logical next step after mastering HTML/CSS - knowing SVG gives you a lot of new options when building your websites.
Fun (and useful) SVG Animation With CSS
Web Directions Respond 2017
by Brett Snaidero
@brettsnaidero : Twitter | @brettsnaidero : Codepen
Hi everyone, my name is Brett Snaidero.
I'm really excited because I'm going to be talking to you a bit about something that I am really passionate about, which is SVG.
But before we dig into it...