Getting started with inline SVG
This May, Viget worked with Dick's Sporting Goods to launch Women's Fitness, an interactive look at women’s fitness apparel and accessories. One of it's most interesting features is the grid of hexagonal product tiles shown in each scene. To draw the hexagons, I chose to use SVG polygon elements.
I've had experience using SVG files as image sources and in icon fonts, but this work was my first opportunity to really dig into it's most powerful use case, inline in HTML. Inline SVG simply refers to SVG markup that is included in the markup for a webpage.
<div><svg><!-- WHERE THE MAGIC HAPPENS. --></svg></div>
Based on this experience, here are a few simple things I learned about SVG.
1. Browser support is pretty good
2. SVG can be styled with CSS
Many SVG attributes, like fill and stroke, can be styled right in your CSS.
3. SVG doesn't support CSS z-index
Setting the z-index in CSS has asbolutely no effect on the stacking order of svg. The only thing that does is the position of the node in the document. In the example below, the orange circle comes after the blue circle in the document, so it is stacked on top.
Creating namespaced elements (or attributes, more on that later) requires a slightly different approach than HTML:
// HTML document.createElement('div'); // SVG document.createElementNS('http://www.w3.org/2000/svg', 'svg');
If you're having problems interacting with or updating elements, double check that you're using
createElementNS with the proper namespace. More on SVG namespaces.
In a Backbone application like Women's Fitness, to use
svg or another namespaced element as the view's
el, you can explictly override this line in
// https://github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L1105 var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
I made a Backbone View for SVG and copied the
_ensureElement function, replacing the line above with this:
// this.nameSpace = 'http://www.w3.org/2000/svg'; this.tagName = 'svg'; var $el = $(window.document.createElementNS(_.result(this, 'nameSpace'), _.result(this, 'tagName'))).attr(attrs);
- Some SVG attributes are namespaced, like the href of an image or anchor:
xlink:href. To set or modify these, use setAttributeNS.
// typical node.setAttribute('width', '150'); // namespaced node.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'https://viget.com');
- Tip: attributes set with jQuery are always converted to lowercase! Watch out for issues like this gem:
// jQuery sets 'patternUnits' as 'patternunits' this.$el.attr('patternUnits', 'userSpaceOnUse'); // Works as expected this.el.setAttribute('patternUnits', 'userSpaceOnUse');
- Another tip: jQuery's
addClassdoesn't work on SVG elements. And element.classList isn't supported on SVG elements in Internet Explorer. But you can stil update the class with
5. SVG can be animated
Browser support: Chrome, Firefox, Safari. Internet Explorer does not support CSS transitions, transforms, and animations on SVG elements. In this particular example, the rotation is broken in Firefox because CSS transform-origin is not supported on SVG elements: https://bugzilla.mozilla.org/show_bug.cgi?id=923193.
Browser support: Chrome, Firefox, Safari. Internet Explorer does not support SMIL animation of SVG elements.
Direct manipulation of SVG element attributes allows for the most control over animations. It's also the only method of the three that supports animation in Internet Explorer. If you are doing a lot of work, there are many libraries to speed up development time like svg.js (used in this example), Snap.svg, and d3.
SVG isn't limited to whatever Illustrator outputs. Using SVG in HTML is well-supported and offers many different options to style and animate content. If you're interested in learning more, check out the resources below.