SVG is arguably going to be the main image format of the modern web. I recently wrote an article for Safari Books Online called SVG Icons for New Devices that covers some of the basics of dealing with SVG. This article covers more the pain points of using SVG in production and as it turns out there are many.
Here's how you link to your amazing vector image.
<img src="/images/logo.svg">
This is pretty straightforward and should work very well for most of your cases. You can also specifcy width
and height
this way or in your CSS.
SVG files are supposed to be human readable, but XML is terrible, so it's been slow going for me. That being said I have noticed one strange thing about the content of SVG files, notably the fact that there are width
and height
attributes:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="15px" height="15px" viewBox="0 0 15 15" enable-background="new 0 0 15 15" xml:space="preserve">
Sometimes in Firefox when you scale up SVG images (browser-zoom) you get some weird bluriness. If you change the width
and height
from px
to em
this bluriness seems to myseriously dissappear. Because in this case it's a sqaure 1em
and 1em
work great. I'm not sure if this is a bug in Firefox or if it's even still a problem in the newer versions. Your mileage may very.
It's pretty easy to use SVG for icons and just make them background images. This is probably your standard use case for SVG anyway.
.icon {
height: 16px;
width: 16px;
background-size: 16px 16px;
}
.icon-arrow {
background: url("/images/icon-arrow.svg") no-repeat;
}
<div class="icon icon-arrow"></div>
EM's are relative to font-size
, so you can easily use them to size your SVG images relative to some text, which can be really helpful in a lot of cases. Here's an exaple of putting them next to some headings.
h1 {
font-size: 24px;
}
h2 {
font-size: 18px;
}
.icon-before {
background-size: 1em 1em;
padding-left: 1em;
}
.icon-arrow {
background: url("/images/icon-arrow.svg") no-repeat;
}
<h1 class="icon-before icon-arrow">Header 1 w/Icon</h1>
<h2 class="icon-before icon-arrow">Header 2 w/Icon</h2>
If you care about IE8 or Android 2.x or other browsers that don't support SVG images you can combine some fanciness like this with a simple custom build of modernizr to easily fallback without too much ugliness.
.icon {
height: 16px;
width: 16px;
background-size: 16px 16px;
background-repeat: no-repeat;
}
/* only show svg icon */
.svg .icon-arrow {
background-image: url("/images/icon.svg");
}
/* don't show anything but png */
.no-svg .icon-arrow {
background-image: url("/images/icon.png");
}
<div class="icon icon-arrow"></div>
Note: With this approach we do have to wait until modernizr adds our svg
or no-svg
classes to the pages <body>
before the images show up. Other fallback approaches can avoid the wait, but this guarantees the right thing will show up in the right browser.
Another Note: Someone really needs to write a Sass plugin one day to create the PNG images directly from the SVG, so that we don't have to bug the designer for it.
Data URI's are this amazing way to embed binary image content directly into your CSS files. This results in a reduce number of seperate downloads and can improve performance in some situations (hover states, etc).
.icon {
height: 16px;
width: 16px;
background-size: 16px 16px;
background-repeat: no-repeat;
}
.icon-arrow {
background-image: url(data:image/svg+xml;base64,..);
}
<div class="icon icon-arrow"></div>
Compass provides the inline-data()
helper to assist with base64ing images and bringing them into your stylesheets. You can also drag and drop your SVG images into the SVG is Rad tool I wrote to get the proper CSS.
In some versions of WebKit (Chrome < 18 and Safari < 6) you cannot combine SVG data-URIs and background-repeat: repeat-x
. The image turns into a blurry mess! Because of this bug in some cases I had to switch to referencing the SVG from a file and it was fine.
If you try to link to external SVG files for background images and don't specify the correct mime type they just won't show up. This happened to us after we switched from base-64 encoded SVGs to linking to files, because the so-called magic mime type detection script in our version of Apache noticed that our SVG files looked like XML and served them up as text/xml.
You can add this to your .htaccess file if Apache is doing the same thing to you (hat tip: this 5 year old article):
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
If you're on NGINX check out this stackoverflow question about SVG MIME types and NGINX.
Other people are doing a lot of interesting things with SVGs at the moment. Here are some topics I don't know quite enough about at the moment: