Using SVG

SVG is an image format for vector graphics. It literally means Scalable Vector Graphics. Basically, what you work with in Adobe Illustrator. You can use SVG on the web pretty easily, but there is plenty you should know.

Why use SVG at all?

  • Small file sizes that compress well
  • Scales to any size without losing clarity (except very tiny)
  • Looks great on retina displays
  • Design control like interactivity and filters

Getting some SVG to work with

Design something in Adobe Illustrator. Here’s a Kiwi bird standing on an oval.

Notice the artboard is cropped up right agains the edges of the design. Canvas matters in SVG just like it would in PNG or JPG.

You can save the file directly from Adobe Illustrator as an SVG file.

As you save it, you’ll get another dialog for SVG Options. I honestly don’t know much about all this. There is a whole spec for SVG Profiles. I find SVG 1.1 works fine.

The interesting part here is that you can either press OK and save the file, or press “SVG Code…” and it will open TextEdit (on a Mac anyway) with the SVG code in it.

Both can be useful.

Using SVG as an <img>

If I save the SVG to a file, I can use it directly in an <img> tag.

<img src="kiwi.svg" alt="Kiwi standing on oval">

In Illustrator, our artboard was 612px ? 502px.

That’s exactly how big the image will on the page, left to itself. You can change the size of it though just by selecting the img and changing its width or height, again like you could a PNG or JPG. Here’s an example of that:

Check out this Pen!

Browser support

Using it this way has its own set of specific browser support. Essentially: it works everywhere except IE 8 and down and Android 2.3 and down.

If you’d like to use SVG, but also neeed to support these browsers that doen’t support using SVG in this way, you have options. I’ve covered different techniques in different workshops I’ve done.

One way is to test for support with Modernizr and swap out the src of the image:

if (!Modernizr.svg) { $(".logo img").attr("src", "images/logo.png");
}

David Bushell has a really simple alternative, if you’re OK with JavaScript in the markup:

<img src="image.svg" onerror="this.onerror=null; this.src='image.png'">

SVGeezy can also help. We’ll cover more fallback techniques as this article progresses.

Using SVG as a background-image

Similarly easy to using SVG as an img, you can use it in CSS as a background-image.

<a href="/" class="logo"> Kiwi Corp
</a>
.logo { display: block; text-indent: -9999px; width: 100px; height: 82px; background: url(kiwi.svg); background-size: 100px 82px;
}

Notice we set the background-size to the size of the logo element. We have to do that otherwise we’ll just see a bit of the upper left of our much larger original SVG image. These numbers are aspect-ratio aware of the original size. But you could use a background-size keywords like contain if you want to make sure the image will fit and can’t know the parent image will be of the exact right size.

Browser support

Using SVG as background-image has its own special set of browser support, but it’s essentially the same as using SVG as img. The only problem browsers are IE 8 and down and Android 2.3 and down.

Modernizr can help us here, and in a more efficient way than using img. If we replace the background-image with a supported format, only one HTTP request will be made instead of two. Modernizr adds a class name of “no-svg” to the html element if it doesn’t support SVG, so we use that:

.main-header { background: url(logo.svg) no-repeat top left; background-size: contain;
} .no-svg .main-header { background-image: url(logo.png);
}

The problem with both <img> and background-image…

Is that you don’t get to control the innards of the SVG with CSS like you can with the following two ways. Read on!

Using “inline” SVG

Remember how you can grab the SVG code right from Illustrator while saving if you want? (You can also just open the SVG file in a text editor and grab that code.) You can drop that code right into an HTML document and the SVG image will show up just the same as if you put it in an img.

<body> <!-- paste in SVG code, image shows up! --> </body>

This can be nice because the image comes over right in the document and doesn’t need to make an additional HTTP request. In other words, it has the same advantages as using a Data URI. It has the same disadvantages too. A potentially “bloated” document, a big chunk of crap right in the document you’re trying to author, and inability to cache.

If you’re using a back end language that can go fetch the file and insert it, at least you can clean up the authoring experience. Like:

<?php include("kiwi.svg"); ?>

Optimize it first

Likely not a huge shocker, but the SVG that Adobe Illustrator gives you isn’t particularly optimized. It has a DOCTYPE and generator notes and all that junk. SVG is already pretty small, but why not do all we can? Peter Collingridge has an online SVG Optimiser tool. Upload the old, download the new. In Kyle Foster’s video, he even takes it the extra mile and removes line breaks after this optimization.

If you’re even more hardcore, here is a Node JS tool for doing it yourself.

Now you can control with CSS!

See how the SVG looks a lot like HTML? That’s because they are both essentially XML (named tags with angle brackets with stuff inside). In our design, we have two elements that make up the design, an <ellipse> and an <path>. We can jump into the code and give them class names, just like any other HTML element can have.

<svg ...> <ellipse class="ground" .../> <path class="kiwi" .../>
</svg>

Now in any CSS on this page we can control those individual elements with special SVG CSS. This doesn’t have to be CSS embedded in the SVG itself, it can be anywhere, even in our global stylesheet <link>ed up. Note that SVG elements have a special set of CSS properties that work on them. For instance, it’s not background-color, it’s fill. You can use normal stuff like :hover though.

.kiwi { fill: #94d31b; }
.kiwi:hover { fill: #ace63c; }

Even cooler, SVG has all these fancy filters. For instance blurring. Chuck a filter in your <svg>:

<svg ...> ... <filter id="pictureFilter" > <feGaussianBlur stdDeviation="5" /> </filter> </svg>

Then you can apply that in your CSS as needed:

.ground:hover { filter: url(#pictureFilter);
}

Here’s an example of all that:

Check out this Pen!

Browser support

Inline SVG has it’s own set of browser support, but again, it’s essentially only an issue in IE 8 and down and Android 2.3 and down1.

One way to handle fallbacks for this type of SVG is:

<svg> ... </svg>
<div class="fallback"></div>

Then use Modernizr again:

.logo-fallback { display: none; /* Make sure it's the same size as the SVG takes up */
}
.no-svg .logo-fallback { background-image: url(logo.png); }

Using SVG as an <object>

If “inline” SVG just isn’t your jam (remember it does have some legit drawbacks like being hard to cache), you can link to an SVG file and retain the ability to affect its parts with CSS by using <object>.

<object type="image/svg+xml" data="kiwi.svg" class="logo"> Kiwi Logo <!-- fallback image in CSS -->
</object>

For the fallback, Modernizr detection will work fine here:

.no-svg .logo { width: 200px; height: 164px; background-image: url(kiwi.png);
}

This will work great with caching and actually has deeper support than using it any other way. But, if you want the CSS stuff to work, you can’t use an external stylesheet or <style> on the document, you need to use a <style> element inside the SVG file itself.

<svg ...> <style> /* SVG specific fancy CSS styling here */ </style> ...
</svg>

Data URI’s for SVG

A way to shrink SVG’s even smaller is to convert them into Data URI’s. Mobilefish.com has an online conversion tool for that. Simply paste in the contents of your SVG file and fill out the form and it will display the results in a textarea for you to copy. Remember to remove line breaks in the data it gives you back. It looks like pure gibberish:

You can use that anywhere we’ve talked about so far (except inline <svg> because that just doesn’t make sense) Just put the gibberish where it says [data] in these examples.

As <img>

<img src="data:image/svg+xml;base64,[data]>

As CSS

.logo { background: url(data:image/svg+xml;base64,[data]);
}

As <object>

<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]> fallback
</object>

And yep, if you have an embedded <style> in your SVG before you base64 it, it will work if you use it as an <object> still!

For the hardcore, Filament group has grunticon for automating the process.

Command line thingy for base64ing SVG:

Or alternatively Mathias Bynens has some techniques:

Use openssl base64 < path/to/file.png | tr -d 'n' | pbcopy or cat path/to/file.png | openssl base64 | tr -d 'n' | pbcopy to skip writing to a file and just copy the base64-encoded output to the clipboard without the line breaks.

Related Stuff!

Kyle Foster’s An Optimized SVG Workflow, which is worth an embed:


1 And speaking of Android 2.3 browser…

Using SVG is a post from CSS-Tricks

TOP
Visit Us On TwitterVisit Us On FacebookVisit Us On Google PlusVisit Us On Linkedin