News

Create animated SVG icons for the web

Utilising the power of SVG, HTML5 and CSS we show you how to create resolution-friendly animated vector icons for the web

15

As a designer you’re not only worrying about the multiple layouts needed for today’s ever-expanding list of viewport sizes, but you have another problem: an increasing number of resolutions – retina screens being an example.

Solutions have ranged from using font icons, which are cool for simple monochrome icons, to creating separate icons for every screen resolution you’d like to handle, which is time consuming, but guaranteed to work. Both are reasonable solutions in their own way but if you’ve used them you’ll know that they’re far from optimal and take up a lot of time when tackling complex design problems.

Thankfully the dream of creating a design-once-use-everywhere graphic is now a reality thanks to increasing support for the SVG standard. In this tutorial we’re going to show a simple workflow that takes a ready-made vector icon in Illustrator and is then exported as pure SVG code, ready to clean up and enhance in a code editor. Finally we’ll add some simple CSS animations to bring the icon to life. It’s assumed that you know your way around Illustrator (or some other vector tool that can export SVG code) and also have a basic understanding of HTML, CSS and XML.

Load vector design

Although you could potentially create your icon in a text editor using just pure XML, it’s actually not that practical for use in a live project – and you’ll probably have a hard time coming up with anything truly creative. So, let’s start with our ready-made icon by opening file ‘fighterjet.ai’ in Adobe Illustrator.

Export SVG code

Next select File>Save As, which should pop up a dialog. Select the ‘Save as type’ drop-down, changing it to SVG, followed by the Save button. Another dialog will pop up with a variety of options. You can leave most of the settings to default or simply use the ones shown in our screenshot. Finally, press ‘Show SVG Code’ to bring up the raw SVG code.

Prepare your HTML

Next we want to set up a basic HTML document as we’re going to have to paste the SVG code inline. Set up the code below, then copy and paste the SVG code we generated earlier where it says <!–SVG Code Goes Here –>. We’ve also included the library ‘prefixfree.min.js’ to save us from bloating our CSS code with vendor-specific prefixes, eg –moz, –webkit.

001    <!DOCTYPE html>
002    <head>
003    <title>SVG Fighter Jet Icon</title>
004    <style> body { background:#3b7172; } </style>
005    </head>
006    <body>
007    <h1>SVG Fighter Jet Icon</h1>
008    <!-- SVG Code Goes Here -->
009    <script type=”text/javascript” src=”prefixfree.min.js”></script>
010    </body>
011    </html>



Clean-up time

Adobe Illustrator has really sped up our workflow by automatically generating pure SVG code for us, but at the same time we can simplify and optimise the code in places. Let’s start with the <svg> tag and strip out everything except the following attributes: version, width, height, viewBox. Let’s also add a class=”icon” attribute for easy CSS control later on.

001    <!-- Bloated Version -->
002    <svg version=”1.1” xmlns=”http://
    www.w3.org/2000/svg” xmlns:xlink=”http://
    www.w3.org/1999/xlink” x=”0px” y=”0px” 
    width=”768px” height=”1024px” viewBox=”0 0
    768 1024” style=”enable-background:new 0 0
    768 1024;” xml:space=”preserve”>

001    <!-- Lean Version -->
002    <svg version=”1.1” width=”768px” 
    height=”1024px” viewBox=”0 0 768 1024” 
    class=”icon”>

Group your code

You’ll notice from the code that the <g> element is very similar to a conventional <div>. It’s used as a wrapper and helps group your elements into easy-to-manage blocks. This is important as if you want to individually target parts of your SVG for styling or animation then you’re going to need these groups. Our code also lacks an overall wrapper, so we’re going to add a new <g> tag with a class of ‘icon_wrapper’.

001    <svg version=”1.1” width=”768px” height=”1024px” viewBox=”0 0 768 1024” class=”icon”>
002        <g class=”icon_wrapper”>
003    …
004            </g>
005    </svg>
006    

More cleaning

Next we’ll selectively add more class attributes to the code as we’ll need to be able to pick out specific parts of the SVG for animation and styling purposes. We’ll add classes to the following elements: Wide_Stream_1_, Narrow_Stream, Booster_Mask and Fighter_Jet. The main parts that will be animated are the jet and the thrusters.

001    <g id=”Booster_Mask” class=”booster_mask”>
002    <defs>
003        <circle id=”SVGID_5_” cx=”427.175”  cy=”530.825” r=”284.175”/>
004    </defs>
005    <clipPath id=”SVGID_6_”>
006        <use xlink:href=”#SVGID_5_”   style=”overflow:visible;”/>
007    </clipPath>
008    <g id=”Wide_Stream_1_” class=”wide_stream” style=”clip-path:url(#SVGID_6_);”>
009        <rect x=”413” y=”700” style=”fill: #BDCCD4;” width=”37” height=”153”/>
010        <rect x=”424” y=”700” style=”fill: #FFFFFF;” width=”15” height=”153”/>
011    </g>
012    <g id=”Narrow_Stream” class=”narrow_stream” style=”clip-path:url(#SVGID_6_);”>
013        <rect x=”425” y=”1130” style=”fill:  #BDCCD4;” width=”13” height=”253”/>
014        <rect x=”428.5” y=”701” style=”fill:none;  stroke:#FFFFFF;stroke-width:3;”  width=”5” height=”253”/>
015    </g>
016    </g>

SVG polygons

So far we’ve seen a number of tags that we haven’t spoken too much about, eg <rect>, <circle> and now <polygon>. These all represent paths within our SVG and are the basic shapes that make up the icon. You’ll note that in the polygon element below it has an inline style called ‘fill’. Most SVG elements have a different set of CSS attributes. In this case, the fill is similar to the conventional ‘background-color’.

001    <g id=”Fighter_Jet” class=”fighter_jet”>
002    <polygon id=”Base_Ship_13_” style=”fill:
    #0F0301;” points=”578.257,608.906 561.
    288,609.033 523.229,541.41 523.139,529.603 
003    478.827,488.281 478.649,464.65 472.569,
    464.696 456.802,413.056 452.164,400.15 451.
    997,377.945 431.616,327.146 431.017,325.655
004    430.471,327.17 410.998,378.253 411.165,
    400.459 406.581,413.433 391.441,465.307 
    385.652,465.35 385.83,488.98 
    342.145,530.963 
005    342.233,542.771 304.904,610.961 287.
    936,611.089 271.706,666.028 309.255,698.
    103 388.196,646.808 401.367,681.659 
006    420.854,697.092 446.646,696.898 465.898,
    681.19 478.553,646.148 558.255,696.292 
    595.311,663.593  “/>
007    …
008    </g>

Font clean-up

At this point if you’ve previewed your HTML file you’ll notice that after the export the fonts aren’t showing correctly. This usually happens due to the font names not lining up perfectly. To fix this, we’ll add a simple @font-face block within the <head><style> block.

001    @font-face {
002        font-family: ‘BebasNeueRegular’;
003        src: url(‘fonts/BebasNeue-webfont.eot’);
004        src: url(‘fonts/BebasNeue-webfont.
        eot?#iefix’) format(‘embedded-opentype’),
005            url(‘fonts/BebasNeue-webfont.woff’) 
            format(‘woff’),
006            url(‘fonts/BebasNeue-webfont.ttf’) 
            format(‘truetype’),
007            url(‘fonts/BebasNeue-webfont.
            svg#BebasNeueRegular’) format(‘svg’);
008        font-weight: normal;
009        font-style: normal;
010    }
011    

Fix <text> elements

Now that we have our @font-face entry, let’s find the <text> elements in our code and fix the inline font-family style. This should fix the fonts and they should now look identical to the design in the Illustrator file. At this stage the icon should be looking identical to the design but without any animations.

Style the circle

Let’s begin adding some transitions and animations to our global CSS. To cause the icon circle to contract slightly on hover, we’ll add a .3s transition to the ‘.circle’ element. This effectively means that on hover the outer white stroke of the circle will change from a stroke-width of 15px to 10px, taking approximately .3s.

001    .circle {
002        transition: .3s;
003        fill: #345D5E;
004        stroke: #fff;
005        stroke-width: 15px;
006    }
007    .icon_wrapper:hover .circle { 
008        stroke:#fff;
009        stroke-width: 10px;
010    }

Reposition jet fighter

Next we’ll target the fighter jet. The idea is that when you hover over the jet it moves up by 30px, going from +10px to -20px. This transition takes .2s and utilises the standard transform CSS syntax. If you test the icon right now it should move part of the jet up 30px and contract the outer white circle by 5px.

Animate the boosters

You’ll remember in Step 6 we added a class of ‘narrow_stream’ and ‘wide_stream’ to our SVG. These represent the two stripes of the jet’s thruster. To begin with we’re going to add some simple CSS to hide the ‘.wide_stream’ element and only show it on a hover. Next we’ll animate it for more realism.

Animate thruster

In the below code we’ve added a new animation called ‘thruster_boost’ using the @keyframes rule. All we’re doing here is playing with the opacity of the element. As per the code, we then link this animation up using the animation selector inside ‘.icon_wrapper:hover .wide_stream’. This loops infinitely and applies the animation every .1s.

001    .icon_wrapper:hover .wide_stream { 
002        display: block;
003        animation-name: thruster_boost;
004        animation-duration: .1s;
005        animation-iteration-count: infinite;
006    }
007    @keyframes thruster_boost { 
008        0% {fill-opacity: 1; stroke-opacity: 1; }
009        70% { fill-opacity: 0.5; stroke-opacity:
         0.5; }
010        100% {fill-opacity: 0;stroke-opacity: 0; 011    }
012    }

Tail movement

Here we’ll add a small animation to the tail of the jet, which gives the effect of air turbulence at high speed. Once again, we run the animation infinitely and it repeats every .2s. We’ll look at the animation code next.

Tail shudder animation

Using the keyframes rule we apply a small vertical movement using the translate function, moving the tail up by 1px. Notice that we don’t have to apply a +1px movement to make it go back down. Instead, take a look at Step 14 and notice the animation-direction is set to ‘alternate-reverse’. This means the animation will run one way and then reverse the way it came.

Add some blur

The thruster edges are a little too sharp, so let’s make use of the SVG <feGaussianBlur> filter to soften them up a little. To set up the filter, insert the <filter></filter> code below between the <defs> tags. You can manipulate the ‘stdDeviation’ value to increase or decrease the blur.

Resize your icon

As a final point, if you wanted to adjust the size of the animation, for example, making it half the size, it’s a no brainer. Just change the width and height attributes in the parent SVG tag and you’ll have instantly resized your icon with no loss in quality.

001    <svg version=”1.1” width=”768px”     height=”1024px” viewBox=”0 0 768 1024”     class=”icon”>
002    <!-- Half Size -->
003    <svg version=”1.1” width=”384px”     height=”512px” viewBox=”0 0 768 1024”     class=”icon”>
004    
×