SVG Sprite Sheets

Turns out there are a couple nifty ways to use SVG as a sprite sheet, mentioned in SVG’s fragment identifier section. You can use them anywhere you can use an image. Just drop them into an img tag or a CSS background.

The Original SVG Sprite Sheet

This is the original SVG image, 300 units wide by 100 units tall.

With a Custom View Box

You can set a custom view box on an svg by adding a custom view box fragment identifier to the end of the SVG URL. It would look something like this:

<img src='bunnies.svg#svgView(viewBox(0,0,100,100))'>

Note: You will need to explicitly size the image, as some browsers (CR, S) will not clip to the custom view box.

With a Custom View

You can also target a predefined view element that encapsulates this information. In your SVG you would drop:

<view id='carrot-bunny' viewBox='0 0 100 100' />

Which can then be used in HTML like so:

<img src='bunnies.svg#carrot-bunny'>

Browser Support

Internet Explorer Chrome Firefox Safari Opera iOS Android
9 37 32 7.1 24 8 4.4

Browser support should roughly map to support for SVG fragment identifiers. FF, CR, O versions were only tested for the current release. IE 9 worked, though support is only listed on caniuse as 10 and up. Support for fragment ids is new for the Safari 7.1/iOS 8 release. It only works for image tags (not CSS backgrounds), and is pretty broken for this particular use case.

Safari Issues

While the original issue in Safari 7.1 has been fixed as of Safari 9, the fix does not work for custom viewboxes on an svg as image. This may fix the original problem with icon stacks, though. There are a couple potential workarounds.

  1. Revert to using the image as a CSS background and size/position it as a sprite sheet
  2. Fragment identifiers specifying a viewBox will work with the object or iframe elements.
  3. Fragment identifiers specifying a custom view element in the SVG will work with iframe elements.

So, your best bet is probably to use either iframe with a view element id:

<iframe src='bunnies.svg#carrot-bunny'></iframe>

Or to use object with a custom viewBox fragment id:

<object type='image/svg+xml' data='bunnies.svg?id=one#svgView(viewBox(0,0,100,100))'></object>
<object type='image/svg+xml' data='bunnies.svg?id=two#svgView(viewBox(100,0,100,100))'></object>
<object type='image/svg+xml' data='bunnies.svg?id=three#svgView(viewBox(200,0,100,100))'></object>

Notes & Credits

SVG sprite sheets are similar to icon stacks, and unfortunately suffers similar issues in Safari. What I like about this method is that all artwork is visible in the original image, and you don’t have to do any style tinkering. You do have to do some offset math though, so you’ll have to pick your poison here.

Icons are public domain from Brad Ashburn over on the Noun Project. Inspired by the comments on a WebKit bug about fragment identifier support.

Update 10.23.15: This article originally claimed full support in new versions of Safari. However, in most cases SVG sprite sheets will not work there without using a workaround. The article has been updated, and a full section added on support in Safari.

Update 11.08.15: With Safari 9, image elements basically ignore a custom viewBox on SVG. See support in Safari for more info.