Recently, there’s been a lot of buzz throughout the web design and  development community on using SVG for icons. Due to a number of  limitations and inconveniences, using raster-based images for your  icons, has become an increasingly painful and restricting endevour.
 There are a number of reasons why a raster based image for the  purposes icons, have become obsolete. I covered this and explored a  number of viable solutions in this article 
here,  which is worth reading if you are mostly unfamiliar with the use of SVG  in web development. I explored a number of different methods of  implementing icons including, pure CSS, icon fonts, and SVG. However a  lot of people are still unfamiliar with SVG styling and implementation,  as there isn’t yet a widely-accepted definitive way that works well.
 Which brings us to this article. In this tutorial I will be showing  you how to create, implement, animate and style SVG icons on the web  using simple markup. I’m assuming, if you’ve made it this far, that you  have at minimal, a basic understanding of CSS, HTML, a little JavaScript  and Adobe Illustrator.
 If you are completely unfamiliar with SVG, I would recommend reading 
this article on SVG basics over at CSS-Tricks prior to going any further.
 Let’s get started.
 
Prepping SVG
For the purposes of this article, we are going to be using a rocket icon (originally designed by 
Pierre Borodin), although I slightly modified the icon and converted it to SVG. You can download the Adobe Illustrator file 
here. On a side note, if you prefer to work with your own icon, feel free to do so, the basic methods will remain the same.
 Open up the file in Illustrator, click “
Save As” and select “
.SVG“. Once you click save, the “
SVG Save Options” dialog will pop-up. You can then click on “
SVG Code” which will open the XML code for the file in a text editor. 

 This is a useful feature, however all the CSS that is used to style the SVG is embedded in “
inline” format within the various paths. This is a problem, as we won’t be able to do any custom styling or animation. 

 Separating all that CSS manually would be a pain, so we are going  separate it automatically later. For now, go ahead and save the SVG  using all the default save options.
 To seperate all the CSS so it’s not inline we’ll use a free online 
SVG Optimiser tool by Peter Collingridge. Upload the SVG you saved from Illustrator, check the “
convert styles to CSS” box and download the new SVG file. Open the file up in a text editor or whatever program you use to code. 

 You’ll notice that all the CSS styling is now separated from all  SVG-path markup, which is good. You’ll also notice that there are a  number of class’s and ID’s attached within the markup, similar to  traditional HTML markup. Additionally you should see some “
<g></g>” elements.
 The classes and IDs work pretty much the same as HTML and can be  manipulated in CSS. In SVG <g> is a grouping element and works in a  similar way as a”div” would in HTML. It’s worth noting that when you do  your designing in Illustrator, a layer will be represented as a group  (<g>) in SVG markup, which is all the more reason to name and  organise your layering appropriately. 
 
 
Cleaning Up SVG for Web Use
In order to use SVG’s to to their full potential, we need to clean a  few things up. There are two things we need to do. Firstly –  Illustrator’s back-end leaves all the grouping ID’s with arbitrary  characters in their name. Secondly, the SVG optimizer we used, adds  generic styling classes such as “
style1, style2, style 3“..etc. We need to go through the file and rename all the styles and IDs appropriately so we can work on them later.
 Here I have cleaned up the SVG markup, which looks like this: 
<svg  version="1.1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="307px"
height="283px" viewBox="0 0 307 283" enable-background="new 0 0 307 283" xml:space="preserve">
<g class="rocket_wrap">
<circle cx="147.5" cy="138.6" r="105.5" class="icon_circle"/>
<g class="rocket_inner">
<g class="fire" id="fireMiddle">
<path class="fire_path" d="M148.891,179.906c3.928,0,7.111,3.176,7.111,7.094   c0,7.78-7.111,16-7.111,16s-7.111-8.349-7.111-16C141.78,183.082,144.963,179.906,148.891,179.906z"/>
</g>
<g class="fire" id="fireRight">
<path class="fire_path" d="M154.063,181.092c3.577-1.624,7.788-0.048,9.408,3.52   c3.216,7.084,0.139,17.508,0.139,17.508s-9.927-4.662-13.09-11.63C148.9,186.923,150.487,182.715,154.063,181.092z"/>
</g>
<g class="fire" id="fireLeft">
<path class="fire_path" d="M143.392,182.519c3.25,2.207,4.098,6.623,1.896,9.864   c-4.372,6.436-14.873,9.238-14.873,9.238s-1.191-10.902,3.108-17.23C135.725,181.149,140.143,180.312,143.392,182.519z"/>
</g>
<g class="fire" id="fireSmallLeft">
<path class="fire_path" d="M143.193  187.531c2.226 0.4 3.7 2.6 3.2 4.8 c-0.875 4.407-5.829 8.264-5.829  8.264s-3.09-5.53-2.229-9.865C138.807 188.5 141 187.1 143.2 187.531z"/>
</g>
<g class="fire" id="fireSmallRight">
<path class="fire_path" d="M152.089  188.599c2.043-0.985 4.496-0.132 5.5 1.9 c1.952 4 0.3 10.1 0.3  10.107s-5.795-2.56-7.713-6.541C149.186 192 150 189.6 152.1 188.599z"/>
</g>
<path class="rocket_bottom" d="M157.069  171.31h-3.292c-1.562-0.048-3.178-0.076-4.846-0.076 s-3.284 0.028-4.846  0.076h-3.292c-7.277-7.938-12.371-26.182-12.371-47.434c0-28.54  9.182-51.676 20.508-51.676 c11.327 0 20.5 23.1 20.5 51.676C169.44 145.1  164.3 163.4 157.1 171.31z"/>
<g id="right_wing_wrap">
<path class="wing_base" d="M166.678 127.161c0 0 17.7 3.3 12.9 48.099l-18.06-14.05 L166.678 127.161z"/>
<path class="wing_shadow" d="M158.225 140.336c10.481-5.584 22.7 22.2 21.4 34.9 l-18.06-14.05C161.542 161.2 156.1 144.3 158.2 140.336z"/>
</g>
<g id="left_wing_wrap">
<path class="wing_base" d="M135.131 161.21l-18.06 14.1 c-4.805-44.793 12.924-48.099 12.924-48.099L135.131 161.21z"/>
<path class="wing_shadow" d="M135.131 161.21l-18.06 14.1 c-1.367-12.746 10.896-40.509 21.377-34.924C140.614 144.3 135.1 161.2 135.1 161.21z"/>
</g>
<g id="rocket_body_wrap">
<path class="rocket_base" d="M162.728  167.358c-3.778-0.623-8.573-0.996-13.796-0.996 s-10.018 0.373-13.795  0.996c-5.033-10.186-8.257-25.808-8.257-43.338c0-30.688 9.873-55.566  22.052-55.566 s22.053 24.9 22.1 55.566C170.984 141.6 167.8 157.2 162.7  167.358z" />
<path class="rocket_shadow" d="M145.464  166.417c19.578-40.575 7.26-85.229 4.112-98.067 c11.88 0.9 21.4 25.4  21.4 55.525c0 17.529-3.225 33.152-8.257 43.337c0  0-3.786-0.472-8.069-0.697 S145.464 166.4 145.5 166.417z"/>
</g>
<g id="large_window_wrap">
<radialgradient id="SVGID_2_" cx="148.9" cy="112.5" r="15.2" fx="139.4853" fy="112.5239" gradientunits="userSpaceOnUse">
<stop offset="0" class="window_grandient"/>
<stop offset="0.5868" class="window_grandient"/>
<stop offset="0.6834" class="window_grandient"/>
<stop offset="0.6845" class="window_grandient1"/>
<stop offset="0.6861" class="window_grandient2"/>
<stop offset="0.6897" class="window_grandient3"/>
</radialgradient>
<circle class="large_window_path" cx="148.9" cy="111.3" r="10.5"/>
</g>
<circle class="small_window_path" cx="148.9" cy="132.4" r="5.2"/>
</g>
</g>
</svg>
Setting Up
We’re going to make 3 states for this icon – a inactive state, a  hover state, and a toggled click state. We’ll use a combination of  mainly CSS, with a tiny bit of JavaScript to achieve this. If you don’t  need the click function and just want a hover state, you can animate  everything using only CSS without including any JavaScript at all.  However I thought we should cover the JavaScript anyway. 

 For the purposes of this tutorial, we’ll be writing all our markup  inline, into one document. However if you’re working on a larger  project, you can easily use PHP, JavaScript or simply an HTML  “<object>” with the src set to the external SVG file to insert SVG  markup into your pages.
 Also, we won’t be adding all the browser prefixes (-webkit, -O-,  etc..) to the CSS, purely for the benefit of not bloating the tutorial  markup. However you should use the correct vendor prefixes to ensure  browser compatibility. You can add browser prefixes automatically using 
this prefixer from Nettuts+.
 Setup a blank HTML document and paste your SVG code into the body,  remove the CSS from SVG markup and place it in the head of document. You  can actually delete the default styles from the document altogether, as  we we’ll be custom styling the icon ourselves. 
Styling SVG with CSS
Now let’s start to style our SVG markup. Before we worry about  animating the icon, let’s just focus on making the hover and inactive  states. We’ll start with the inactive state:
 /*=============================================
[ Page Setup ]
==============================================*/
body{background:#34495e}
#pageWrap {width:100%;overflow:hidden;}
#rocket{display:block;margin:0 auto;margin-top:150px;}
/*=============================================
[ Inactive State Styles ]
==============================================*/
.rocket_inner {
transform: translateY(15px) translateX(-3px);
transition: .3s;
}
.icon_circle {
transition: .2s;
fill: #22303e;
}
.large_window_path {
transition: .2s;
fill: #22303e;
}
.small_window_path {
transition: .2s;
fill: #22303e;
}
.wing_shadow {
fill: #34495e;
}
.rocket_bottom { fill: #34495e }
.rocket_base { fill: #34495e }
.rocket_shadow { fill: #34495e }
.window_grandient { stop-color: #2DCB73 }
.window_grandient1 { stop-color: #2AC16D }
.window_grandient2 { stop-color: #29B968 }
.window_grandient3 { stop-color: #28B767 }
.wing_base { fill: #34495e }
.fire_path { fill: #FC0 }
.fire {display: none;}
As you can see, there are a number of elements we have styled using 
SVG styling markup for CSS.  You can get more intricate with your styling, however you mostly only  need to use the fill, stroke and stroke-width attributes. You’ll notice  there’s a gradient fill as well, which was setup in Illustrator. This  makes a reflection-gradient for the top window on the rocket once it’s  animated.
 If you load your page in the browser now, your icon should look like this: 
 
 
Now into the hover effect. SVG class’s and IDs act as you would  expect them to in regards to CSS. We can add a number of hover effects  using 
attributes. 
/*=============================================
[ Hover Styles ]
==============================================*/
.rocket_wrap:hover .icon_circle {
fill: #34495e;
stroke: #fff;
stroke-width: 3px;
}
.rocket_wrap:hover .rocket_base {
fill: #fff;
stroke: #fff;
stroke-width: 3px;
}
.rocket_wrap:hover .small_window_path {
fill: #34495e;
stroke: #fff;
stroke-width: 2px;
}
.rocket_wrap:hover .rocket_bottom {
fill: #fff;
stroke: #fff;
}
.rocket_wrap:hover .wing_base {
fill: #fff;
stroke: #fff;
stroke-width: 3px;
}
.rocket_wrap:hover .large_window_path {
fill: #34495e;
stroke: #fff;
stroke-width: 2px;
}
.rocket_wrap:hover .wing_shadow { display: none }
.rocket_wrap:hover .rocket_shadow { fill: #fff }
Here we are basically changing the fill and stroke colors along with  the stroke widths. It’s relatively straight forward and mostly  self-explanatory. You can play around with all kinds of things like  opacity, sizes, stroke caps and more.
 Load your page again and hover on/off the icon. It should change states. Pretty cool right? 
 
 
Animating SVG With CSS
There are a number of JavaScript plugins to animate SVG, and I expect  these will develop further and become more user-friendly in the future.  However you can achieve most effects using simple CSS and CSS  keyframes. If you’re not familiar with CSS keyframes, Chris Coyier has a  good intro article 
here on CSS-Tricks.
 If you don’t want any JavaScript, you can use CSS “
@keyframe” animation properties using simple “
:hover”  effects. However we will use a little bit of JavaScript to toggle them  on click. We’ll get to that later though, for now let’s just set-up the  keyframes and click classes.
 We’ll setup our animation through 3 sets of classes. The SVG paths  that don’t require animation but simply need to change color, will have a  clicked class. Then for the elements that need to be animated, we’ll  add a clicked class which contains the animation name of an “
@keyframe” animation. Then we’ll apply them to their respective elements with a “.
click” function using JavaScript.
 Let’s look at the static elements that just need a color change: 
/*=============================================
[ Clicked Styles ]
==============================================*/
.baseClicked {
fill: #FFFFFF !important;
stroke-width: 0px !important;
}
.shadowClicked {
fill: #EDEDED !important;
stroke-width: 0px !important;
}
.iconCircleClicked {
fill: #282e3a !important;
stroke: #fff !important;
stroke-width: 7px !important;
}
.smallWindowClicked {
fill: #28B767 !important;
stroke-width: 0px !important;
}
.wingShadowClicked {
display: block !important;
fill: #FC9252 !important;
}
.wingBaseClicked {
fill: #E16E36 !important;
stroke-width: 0px !important;
}
.rocketBottomClicked {
fill: #2DCB73 !important;
stroke-width: 0px !important;
}
.largeWindowClicked {
fill: url(#SVGID_2_) !important;
stroke-width: 0px !important;
}
.innerClicked { transform: translateY(0px) translateX(-3px) !important; }
These are our classes that we’ll append to the icon’s various  elements later. Again, these are mostly self explanatory changes to fill  and stroke attributes. You’ll notice however that they all have an “!important”  declaration. This resolves the issue of CSS hover effects being  displayed while JavaScript click classes are active by overriding the “:hover” property.
 Now for the animation of the fire. You’ll notice the SVG file has 5  fire flames at the bottom. By default these aren’t visible as we have  made them invisible using CSS using “display:none” Each fire  element has it’s own ID, while sharing the same class. This way we can  display them all at once while animating them individually.
 Let’s add our animation markup:
 
/*=============================================
[ Animation Classes ]
==============================================*/
.fire {
display: none;
animation-delay: 0s;
fill-opacity: 1;
animation-timing-function: ease-in;
stroke-width: 0px;
animation-iteration-count: infinite;
animation-timing-function: linear;
transform-origin: 50% 50%;
animation-direction: normal;
}
.clickedLeft {
display: block;
animation-delay: 0s;
animation-name: fireLeft, fillOpacity1;
animation-duration: 1.2s;
}
.clickedMiddle {
display: block;
animation-delay: 0s;
animation-name: fireMiddle, fillOpacity1;
animation-duration: 1s;
}
.clickedRight {
display: block;
animation-delay: 0s;
animation-name: fireRight, fillOpacity1;
animation-duration: 1.3s;
}
.clickedSmallLeft {
display: block;
animation-delay: 0s;
animation-name: fireSmall, fillOpacity2;
animation-duration: 1.3s;
transform-origin: bottom;
}
.clickedSmallRight {
display: block;
animation-delay: 0.3s;
animation-name: fireSmall, fillOpacity3;
animation-duration: 1.6s;
transform-origin: bottom;
}
Notice we have two “animation-name“s for each element, one  for fill-opacity and another for transforms. The reason we’re not using a  single animation for every element is so it they all animate in  slightly different ways. If they all shared a single keyframe animation,  the result would look automated an unnatural. If you don’t want to use  any JavasSript, you can add these classes as CSS “:hover” effects using  the regular mark-up classes.
 Let’s setup the keyframes:
 
/*=============================================
[ KeyFrame Animations ]
==============================================*/
@keyframes fireSmall {
10% { transform: rotate(17deg) translateY(1px) }
20% { transform: rotate(-13deg) translateY(2px) }
30% { transform: rotate(21deg) translateY(3px) }
40% { transform: rotate(-34deg)translateY(4px) }
50% { transform: rotate(24deg) translateY(5px) }
60% { transform: rotate(-17deg) translateY(6px) }
70% { transform: rotate(31deg) translateY(7px) }
80% { transform: rotate(-28deg) translateY(8px) }
90% { transform: rotate(14deg) translateY(9px) }
99% { transform: rotate(0deg) translateY(10px) }
}
@keyframes fireLeft {
6% { transform: rotate(25deg) }
15% { transform: rotate(-19deg) }
25% { transform: rotate(25deg) }
32% { transform: rotate(-30deg) }
46% { transform: rotate(22deg) }
54% { transform: rotate(-29deg) }
61% { transform: rotate(32deg) }
74% { transform: rotate(-9deg) }
83% { transform: rotate(16deg) }
99% { transform: rotate(0deg) }
}
@keyframes fireMiddle {
10% { transform: rotate(25deg) }
20% { transform: rotate(-25deg) }
30% { transform: rotate(30deg) }
40% { transform: rotate(-22deg) }
50% { transform: rotate(29deg) }
60% { transform: rotate(-45deg) }
70% { transform: rotate(37deg) }
80% { transform: rotate(-15deg) }
90% { transform: rotate(16deg) }
99% { transform: rotate(0deg) }
}
@keyframes fireRight {
15% { transform: rotate(17deg) }
23% { transform: rotate(-13deg) }
37% { transform: rotate(21deg) }
45% { transform: rotate(-34deg) }
54% { transform: rotate(24deg) }
67% { transform: rotate(-17deg) }
72% { transform: rotate(31deg) }
84% { transform: rotate(-28deg) }
96% { transform: rotate(14deg) }
99% { transform: rotate(0deg) }
}
@keyframes fillOpacity1 {
0% {
fill-opacity: 1;
stroke-opacity: 1;
}
50% {
fill-opacity: 1;
stroke-opacity: 1;
}
100% {
fill-opacity: 0;
stroke-opacity: 0;
}
}
@keyframes fillOpacity2 {
0% {
fill-opacity: 1;
stroke-opacity: 1;
}
25% {
fill-opacity: 1;
stroke-opacity: 1;
}
100% {
fill-opacity: 0;
stroke-opacity: 0;
}
}
@keyframes fillOpacity3 {
0% {
fill-opacity: 1;
stroke-opacity: 1;
}
67% {
fill-opacity: 1;
stroke-opacity: 1;
}
100% {
fill-opacity: 0;
stroke-opacity: 0;
}
}
@keyframes rocektMove {
0% { transform: translateY(0px) }
100% { transform: translateY(20px) }
}
This sets-up our keyframing for the fire animation as well as the  rocket itself. CSS uses percentages to set each keyframe at a percentage  of the total animation, which is defined in time using the “
animation-duration:” attribute. 
Applying CSS Classes to SVG using JavaScript
This ins’t something that is easy to achieve, there are a number of complications to consider.
 Firstly jQeury selectors don’t work on SVG markup. So you can’t  select a class/ID and add/toggle a CSS class the way you normally would.  Fortunately Keith Wood has built a number of 
JavaScript plugins specifically for this (and for other SVG/jQuery related issues). We  need to include his plugin so our JavaScript can read the SVG DOM. Head  over and download the jQuery plugin 
here and add the “
jquery.svg.js” and “
jquery.svgdom.js” files to your document folder, as well as including a jQuery library.
 Insert the following in the head of your document below the CSS. 
<script src="jquery.min.js"></script>
<script src="jquery.svg.js"></script>
<script src="jquery.svgdom.js"></script>
Now we can access the SVG DOM using JavaScript selectors and add our  CSS animation classes. Add the following below the SVG markup of the  document:
 
<script type="text/javascript">
$(".rocket_wrap").click(function() {
$("#fireLeft").toggleClass("clickedLeft");
$("#fireMiddle").toggleClass("clickedMiddle");
$("#fireRight").toggleClass("clickedRight");
$("#fireSmallRight").toggleClass("clickedSmallRight");
$("#fireSmallLeft").toggleClass("clickedSmallLeft");
$(".rocket_inner").toggleClass("innerClicked");
$(".rocket_base").toggleClass("baseClicked");
$(".rocket_shadow").toggleClass("shadowClicked");
$(".large_window_path").toggleClass("largeWindowClicked");
$(".small_window_path").toggleClass("smallWindowClicked");
$(".rocket_bottom").toggleClass("rocketBottomClicked");
$(".wing_base").toggleClass("wingBaseClicked");
$(".wing_shadow").toggleClass("wingShadowClicked");
$(".icon_circle").toggleClass("iconCircleClicked");
});
</script>
Again, this is pretty self explanatory. If you’re not that familiar with jQuery, we are setting a click function for the 
rocket icon,  then using a toggle function to add/remove the CSS animation classes.  As we noted above, the “!impotant” deceleration in CSS will override the  hover state when these are added.
 There are some considerations here though. Most notably that you can  only access inline, internal SVG DOMs with jQeury. If you use a data  attribute in an <object> for an externally stored SVG file, the  jQuery won’t work. However, as I noted above there are a number of  solutions to this issue depending on what you’re working with. I have  included some links in the additional info section at the bottom of this  article. 
An Update On Firefox (Updated 23.12.2013)
After playing around with a number of CSS properties regarding the  animation of SVG, I realised that Firefox does not interpret the CSS  attribute “
transform-origin:” when animating SVG groups  (<g>). Regardless of whether you prefix it, or where you put it  (either in the @keyframe or on the group  selector). So “
-moz-transform-origin:” won’t work, no matter what.
 However it does work on SVG paths. If you’re not rotaing anything,  this probably won’t cause an issue. However to ensure browser  compatibility, you should use ID and class selectors on the SVG path  elements, not groups. Hopefully this get’s fixed some time soon by the  Moz dev team.
 The only issue this causes is that animating a group of paths with  the same transform origin can be fickle, as you need to go through each  path element and set their individual transform origins to the same  point relative to each path (rather than just grouping them). 
Summary
So as you can see, we are able to animate SVGs with simple CSS “
@keyframe”  animations. The demo above shows the animation with no jQuery at all.  Having said that, this is just one way to animate SVG using simple  markup. There are already a number of jQuery libraries, plugins and  other useful web apps that you can use. I’ve included a number of useful  links below.
 On a final note, one thing I’d like to add is the best thing about  animating an icon this way and probably the biggest advantage over using  a third-party plugin, is that you can include all your CSS styling and  animation mark-up directly in the SVG file itself (rather than in your  page’s stylesheet). This is seriously the best thing about it, as it  doesn’t bloat or effect existing mark-up. Furthermore, if you do a lot  of work for clients, once you’ve set up all your icons, you can keep all  the animations set-up in the SVG, which makes it really easy and  efficient. Simply use a html “<object>” with the source to your  SVG and all the animation and styling is ready to go!
 I hope you’ve enjoyed this tutorial. 
Additional Info
Here are some useful SVG related links: 
What are your thoughts on animating SVG? Are you new to CSS keyframing? Let us know your thoughts in the comments below.