SVG, or Scalable Vector Graphics, is a XML-style markup driven vector graphic rendering engine for the browser. SVG is supported in every browser, except IE < v9 and Android < v3. The same support is available for canvas (except canvas goes all the way back on Android), so the question often surfaces: which one should you use?
Today, we will survey SVG, and explain why the question of "which one should I use?" is usually answered by "what am I trying to do?". To get a full list of elements that make up SVG, check out Mozilla's docs on the subject. You can see the SVG DOM API there as well.
Overview
We'll begin by outlining some unique advantages of SVG. Then, instead of reviewing all 80 SVG node types, we will explain how Illustrator can quickly get an SVG document into a web page. We'll also take a look at D3.js, a powerful SVG manipulation JavaScript library.
"SVG is not meant to be used for pixel manipulation."
Major Advantages of SVG
SVG has quite a few advantages over images or canvas-based renderings for certain applications. SVG is not meant to be used for pixel manipulation; however, it handles vector graphics and programmatic vector manipulation very well.
Resolution Independence
In case you haven't heard, resolution independence and browser agnosticism is a hot topic in front-end development (think "responsive design") these days. Most of the solutions that exist to fix resolution-based issues (for retina screens, for instance) involve either a large amount of unnecessary data downloaded (hi-res image replacement) or compromise for one browser or the other (upping all resolutions, even when the screen won't display the difference). This makes us rely on the speed of the data download-speed bottleneck to bring higher resolution images to devices that are often on wireless data networks. Not ideal.
"SVG offers a way to do full resolution graphical elements, no matter what size screen, what zoom level, or what resolution your user's device has."
SVG offers a way to do full resolution graphical elements, no matter what size screen, what zoom level, or what resolution your user's device has. This is something that up until SVG, we only saw with clever element styling via CSS and text rendering. Using divs and :after elements to create simple shapes and other effects is unnecessary with SVG. Instead, you can create vector shapes of all kinds.
Super-Accessible DOM Node-Based API
So you write HTML? JavaScript? CSS? Good. Then you already know a lot of what you need to know to get writing SVG. SVG actually uses an XML-compatible format to define its rendering shapes. Beyond this, you can actually style shapes in CSS, and make them interactive with JavaScript. Multiple JS libraries exist to assist you in this world, like D3.js and Raphael. Here's an example of an SVG element group (the Envato leaf). You can also see this example on JSFiddle.
<svg> <g> <g> <path fill="#8BAC54" d="M28.028,104.509c-35.271,44.527-36.619,105.084-7.616,150.407 c26.073-66.957,58.919-142.287,99.378-209.543C81.802,61.428,46.351,81.377,28.028,104.509z M278.797,11.28 c-0.408-3.492-2.227-6.447-4.845-8.41c-2.5-2.097-5.802-3.197-9.304-2.784c0,0-10.403,2.227-26.959,6.483 C158.62,82.498,93.735,184.229,43.453,281.932c1.875,1.628,3.778,3.255,5.749,4.794c56.202,44.471,137.782,34.972,182.238-21.163 C282.657,200.806,278.797,11.28,278.797,11.28z"/> </g> <g> <path fill="#B1C982" d="M58.392,293.368c59.428-95.491,133.438-188.549,220.117-247.851c0.558-20.869,0.289-34.238,0.289-34.238 c-0.408-3.492-2.227-6.447-4.845-8.41c-2.5-2.097-5.802-3.197-9.304-2.784c0,0-10.403,2.227-26.959,6.483 C158.62,82.498,93.735,184.229,43.453,281.932c1.875,1.628,3.778,3.255,5.749,4.794C52.185,289.102,55.271,291.308,58.392,293.368 z"/> </g> </g> </svg>
The DOM node-based API of SVG is already more accessible than the client-side only canvas API. With this construction you can:
- Create SVG document-based images on the server-side
- Inspect SVG elements like any other HTML element
- Programatically manipulate shapes, styles, and positions with technology you are already familiar with (JavaScript and CSS)
- Attach event handlers to SVG nodes
The DOM API provides a further set of clear advantages for using SVG.
No Unnecessary HTTP Requests
When you use images in an html document with the <img>
tag, you are defining a file that the user's browser will request. This request will take up bandwidth and require more precious time to download. If your image is instead a set of dom nodes, it cuts that extra HTTP request out, making your website faster and more user friendly.
Easy Interactive Scripting
Despite the browser wars, the DOM API, across all browsers, offers an extensive amount of flexibility in terms of scripting interactivity, which extends to SVG elements. Styling SVG happens through CSS. Having browser event APIs available to SVG elements makes interactive behavior scripting a cinch. Simply attach a handler to a specific node of the SVG element, and you're set.
This is not true for elements drawn onto the canvas. Since the canvas is simply a pixel rendering engine, the drawn elements are not kept in memory as objects. The script would have the job of keeping these elements collected, and monitoring all relevant position and size information to look for and fire events in an event loop. Beyond this, z-indexing would have to be handled by the script as well.
Let's take a look at an example. Say you want to detect hover over a circle in canvas. Note: We'll just say the canvas is the full width of the browser window, and we'll use jQuery just to keep the example concise.
var circleCenter = [200, 300], radius = 50; $(window).on("mousemove", function(e){ var mx = e.pageX, my = e.pageY; if (mx > circleCenter[0] - radius && mx < circleCenter[0] + radius && my > circleCenter[1] - radius && my < circleCenter[1] + radius){ // now we are hovering } });
While this isn't necessarily a difficult or uncommon pattern of code, if you're used to the browser API, it seems like a frustrating process just to check for hover. This is a very common pattern in other lower-level interface programming engines like Unity3D or Processing. But in the web world, we have tools at our disposal that already handle a lot of common interactive goals we may have. You could write a set of convenience functions to do common tasks, but wouldn't you rather get to the point? In contrast, we can see the simplicity of the same task using SVG.
$("svg path#circle").on("hover", function(event){ // That's all. });
This is clearly far more time-efficient for developers scripting simple interactivity.
Practical Applications
There are plenty of JavaScript libraries out there for canvas (like KineticJS, which will let you do some pretty awesome stuff. But if you're like me, you're not using full-on physics engines in your web applications. Instead, I'm most often needing scalable icons, interactive graphs, and detailed, aesthetically gorgeous ways of presenting information to my users. Most of the physics I need are simple easing equations. These graphical elements are easily created with SVG, and a multitude of simple physics equations will probably handle the rest of my needs. So let's look at a few practical applications for SVG.
- Graph Because SVG's biggest strength is basic vector shapes, it naturally works very well for graphs and infographics. Not only is it great for creating static graphs from given numbers, but it is also well suited for "live" graphs, fed by AJAX requests, user input, or randomly generated data.
- Road Map Road maps consist of hard lines and exact shapes. These shapes can be represented well with vector graphics, and lend themselves to zooming into the map for further detail.
- Complex UI elements Let's say you wanted a UI element that looked like a stacked pyramid of circles. How would you do this in HTML and CSS? Well, you'd first create a bunch of divs for each hole, giving them each a certain border radius and border styles. Then you'd position them within a containing div. Now, what if you wanted a single gradient over the whole thing? You'd likely have to use masking, or some other technique. You'd rather not use images, as they aren't scalable and can't be programmatically re-rendered or changed. Instead, why not draw the element in Illustrator, and save it out as an SVG file? This would allow you to have a single, scalable element without worrying about managing multiple divs.
- Logos Most logos are vector-based. You could define an SVG document as your logo, and drop it anywhere, scaling on the fly to whatever size it needs to be without compromising quality or taking up too much bandwidth.
- Simple Games It's no secret that canvas is suited well for game rendering. Part of the reason for this is that games are often not dependent on vector graphics; rather, they use pixel-based art and animation. However, SVG is a great alternative for games that require less character animation and more information display (think Sudoku).
Why You Probably Aren't Using It
Now that we've looked at some of the advantages of SVG, let's examine why many developers still choose not to use SVG. There are two main reasons why SVG isn't being used by a lot of developers.
- They have never heard of it or have never thought they needed it, so have ignored it (This one is no longer an excuse!)
- An SVG XML document of any complexity looks relatively archaic and complicated, and seemingly isn't nearly as easy as just using an image.
So of course, nobody really wants to sit and edit the points in the SVG XML. Luckily, no one needs to! This is the part that people often don't realize; there ARE tools to edit SVG, so you don't ever have to do it by hand.
SVG Tools
Illustrator, Inkscape
If you own a vector editor, it most likely can save your file as an svg. Go ahead and try it out. Open Illustrator, draw a circle or two, and then save the file as SVG. Next, open that file in Sublime Text or another text editor. You'll immediately see that, aside from some extra meta data, the SVG XML is ready to drop right into your HTML file. You'll most likely see <g>
(group), <path>
(path), and of course <svg>
(the parent svg) elements.
D3.js
While you are totally able to drop your SVG XML directly into an HTML file, what if you want the SVG to be dynamically created? D3.js is "a JavaScript library for manipulating documents based on data". In other words, it's great for generating SVG elements like bar graphs and line plots based on a set of data. We've chosen to show D3 because of its matching vocabulary to the actual SVG implementation in the browser; be aware that there are other great SVG libraries out in the wild (notably, Raphael.js).
Although D3.js does more than SVG manipulation, for the sake of brevity, that is all we will use it for today. (Make sure you take a look at the examples at the D3.js official site, and check out this workshop Mike has posted on his personal site.)
Example 1: Pulsing Circle
In this first example, we are simply creating a pulsing circle by using Math.sin and an iterator with a setInterval. Pulsing Circle
Example 2: Updating Line Plot
In this example, we are updating a plotted line graph with some random values. Line graph
When Should You NOT use SVG?
SVG will handle a lot of your needs for in-browser image rendering. While there are plenty of reasons to use SVG, as with anything great, there are things that it doesn't do well.
- If your rendering requires thousands of nodes, it's more performant to do the rendering in canvas (as the browser isn't having to create objects for every piece rendered, and also doesn't have to do the vector math required to render the object. Instead, it essentially paints mapped pixels.)
- If your application requires support for IE8, remember that you must either provide another vector fallback (such as the more convoluted VML) or not use vector at all, and instead rely on responsively sized images.
Helpful Links
Here are a few helpful links to get you further entrenched in SVG!
- Raphael.js
- Processing.js, based on the powerful Processing, a Java imaging tool
- jQuery SVG
- Sitepoint article: How to Choose Between Canvas and SVG
- Canvas and SVG Performance
- Nettuts+ article about Raphael
What other uses have you found for SVG? Let us know in the comment section and thank you so much for reading.
Comments