Retina displays are going to drastically change how we design for the web. Vector imagery, most notably SVG, will become a significant tool to display resolution-independent imagery at a reasonable bandwidth footprint. I made the switch to SVG on my site using data URIs a few weeks back and will not be looking back. One thing has gnawed at me when I added the SVGs to my CSS file. It felt wrong to treat those SVGs like a plain images. One considerable strength to SVG is that it’s markup-based. That nagging feeling led me to experiment with a different approach to rendering vector imagery on a website, which I am calling SVG CSS injection.

The Gist

Instead of referencing SVG files in your CSS or adding them as data URIs, you add the SVG markup right above the closing body tag and use Javascript to parse through them and generate CSS rules at runtime. This opens up the opportunity to generate multiple color variations of a vector file on the fly, add/remove SVG filters or combine multiple vector shapes into a single CSS rule.

The following icon is rendered with SVG CSS injection. If you’re interested in, look at the original HTML/CSS source – there’s no reference to these background images.

Advantages

There are four main ways to display vector imagery on the web at this point.

Reduction of page requests
All SVG is pulled down with your HTML file (the one request you can’t remove).
Potentially smaller CSS files
Data URIs are great, but they quickly bloat a CSS file. With this method, you only need to include the SVGs used for a specific page. This can make CSS files considerable smaller if you’re using data URIs. There’s no need to include 20 data URI SVGs if you’re only using 2.
Dynamic SVG modification
With SVG included in your HTML, it is DOM-accessibile. This allows the creation of multiple variations of an SVG based on a single SVG.
Create Advanced Background Rules
Use separate SVGs to build a single multiple backgrounds rule.
No backend integration necessary
Writing inline CSS would get you close (you obviously wouldn’t be able to make client-side modifications), and it would need server-side functionality to make it happen. That can often times be unnecessary or undesirable in cases of prototype development or static site buildouts.

Disadvantages

Reliance on Javascript
Since all CSS rules are created on the client side, if Javascript is turned off in the browser, those SVGs will not be displayed.
Only supports modern browsers
IE8 and below are out of the question.

When to use

Unique imagery for a specific page
The sweet spot for this method is in cases where a vector asset is used on a single page. In this case, adding the SVG into that page’s HTML will have a relatively small impact its file size and will not pollute the main CSS file with a one-off asset. I plan to test this method on the Iconic project page.
Use of SVGs with many color variations
Under normal situations, each color variation of an SVG would need to be a separate file, which can quickly bloat your page size and/or number of requests.
Diverse use of imagery throughout site
If you are using a lot of SVG icons throughout your site (either by using icon fonts or just adding SVGs to your CSS), but only use 2 or 3 icons on a specific page, you can save a lot of kilobytes with this method.
Rapid prototyping
This method is a great solution for quickly dropping in SVG images to a page and changing colors without having to save variation after variation.

Examples & Code

Below are some simple examples of SVG CSS injection in action. You can see more details and code samples at the demo page. It goes without saying that all code is rough and at a proof-of-concept stage.

Modifying SVG Prior to Injection

The original SVG in the footer is black, but additional rules were created at load time.

#35d3e9
#ff9200
#b66dff

#ff006a
#8cdb00
#a1a1a1

Rewriting CSS Rules

Rules can be changed on the fly by parsing SVGs and modifying the fill attributes
Click the icon to change its color.

The code to pull this off is pretty simple. All SVGs are added right above the closing body tag. You’ll notice that I’ve nested the SVG (which is semantically legitimate). The parent SVG tag is hidden by setting the width and height attributes 0. The follow code is an example of the simplest form of SVG CSS injection.

 
<html>
<head>
<title>SVG CSS injection. A simple demo.</title>
<style>
body {
padding:30px;
font-family:'Helvetica', Helvetica, Arial, sans-serif;
}
<!-- You still need to manage all rules around positioning, sizing, repeating, etc. for the background image -->
.icon {
width:132px; padding:140px 20px 10px 20px; text-align:center; background-repeat: no-repeat; background-size:auto 70px; background-position:center center; background-color:#fafafa; box-shadow:0 0 20px rgba(0,0,0,.2); margin:10px; font-size:12px;
}
</style>
</head>
<body>
<h1>SVG CSS injection. A simple demo.</h1>
<div class="icon icon-mail"><span class="label">Mail</span></div>
<svg id="svg-injection-container" width="0" height="0">
<svg id="icon-mail" class="iconic"><svg style="enable-background:new 0 0 32 24" xmlns="http://www.w3.org/2000/svg" height="24px" width="32px" y="0px" x="0px"  viewBox="0 0 32 24"><g fill="#010101"> <polygon points="16 11 32 3.9 32 0 0 0 0 3.9"/> <polygon points="16 16 0 8.3 0 24 32 24 32 8.3"/></g></svg>
</svg>
</svg>
<script src="svg-css-injector.js"></script>
<script>new Iconizer('#svg-injection-container .iconic')</script>
</body>
</html>

It’s important to note that this process simply creates a background-image rule for each SVG node. This means that sizing, positioning, repeating, etc. needs to be handled manually.

Next Steps

All code for this project is available on Github. The SVG injector class needs to be significantly improved before it can be usable in the wild. I also would like be interested in making some server-side scripts to make including SVGs less laborious. More importantly though, I would like to get more feedback from both the design and development community on the approach. While I think this method has promise, I want to hear others weigh in on the conversation.