SVG CSS Injection—A Different Approach Towards SVG Rendering

SVGs will be playing a major role in our new retina-display world. If we are going to be using SVGs, why not take advantage of their markup structure?

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.


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.


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.



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.

<title>SVG CSS injection. A simple demo.</title>
body {
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;
<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="" 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>
<script src="svg-css-injector.js"></script>
<script>new Iconizer('#svg-injection-container .iconic')</script>

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.

23 thoughts on “SVG CSS Injection—A Different Approach Towards SVG Rendering”

  1. It’s an interesting idea.
    Surely another disadvantage is if the svg is large and needs to be on many different pages. In this case you will add bloat to many html pages, instead of the svg being loaded from cache…

    1. Yeah, that can definitely become an issue if the SVGs are considerably large. If you are using a specific SVG asset on many different pages, you’ll definitely want to add it to your CSS file as a data URI. However, if the SVG is only going to be used on one or two pages, I think there’s a good argument for using a method like this.

  2. I’m wondering if using apache SSI would benefit this technique, you could simply define an html file for each SVG (or a collection of SVG’s, social, technical, etc) and add an SSI reference to it:

    That would still show a bloated source code afterwards but at least it would be easier to manipulate the code while building it…

    Still a very interesting technique, sort of like FXG’s on actionscript/Flex

  3. Having looked at and played with various options for graphic elements on web pages, as great as they all are, it currently seems that they are limited to a particular style at the moment. In particular, the solid fill. I may be missing much and as great as it looks, there are many instances where for lack of a better word, the graphics need to be ‘richer’.

    You see any scope there?

    1. Yes, it’s limited to a single fill and it’s definitely a considerable limitation. For basic icons, a single fill should suffice, but for complex imagery, it will cause issues. The method definitely has its limitations and its “sweet spot” for usage.

  4. I think (and please correct me if I’m wrong) that someone could also inject rules like:

    to create gradient fills for the SVG graphics. And then use the Fill attribute like: fill=”url(#grad1)”

    What do you think?

  5. For some latest projects I’ve been using SVG as well, it works fine, though I have to agree it would be better if it could be done though the CSS file. There were to many issues still. But you can fill your object with a gradient, not just a single fill.
    Also cool is, SVG renders better crisp and sharp than a font file. And (O yeah) it works with transitions animation and 3D (Safari and Chrome only off course).

  6. This is very interesting! One thing I have been struggling to find a solution for over the past couple of weeks is a way to display content with backgrounds that have multiple angles on them, especially without having a straight vertical edge. Check this for an example. I thought of using SVG, but I wasn’t able to place content over the SVG. Using SVG in CSS made sense, but then came the problem that the height and width would have to be specified. Your method could be a solution to my problem. I’ll have to play around with it. If anyone else has experience with what I’m trying to accomplish, I’d love to hear about it.

  7. I think you need to specify width and height on your .icon-cog class. I realized something was missing when you mentioned “…the following icon…” and I saw nothing. I played around in dev tools and set width/height on the class and lo and behold I could see the cog graphic! 🙂

  8. One way to avoid bloat in your HTML if you have SVG images that you will be using on many pages is to keep your commonly used SVG in a separate (cacheable) file, and load it with an XHR request and insert it into the DOM. Its pretty similar to the CSS sprite technique, except that you have to insert the SVG into the DOM manually.

  9. Can a SVG have a image (bitmap) as a background? I think I tried this once and couldn’t get it to work. I realize it defeats your intention of eliminating extra file requests. But it wold sure be useful as a method to crop an image with vector edges

Leave a Reply

Your email address will not be published. Required fields are marked *