
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