Using SVG to Make Images Look Great on Retina Displays

I recently made some changes to the Constant Contact website and updated our logo from a Portable Network Graphic (PNG) to a Scalable Vector Graphic (SVG).

There are important benefits to using SVGs over PNGs. SVGs offer resolution-independent, fully scalable and crystal clear graphics. Because SVG is a resolution-independent vector format, SVG images are always rendered sharp, regardless of display resolution. SVG uses XML to define paths and shapes to create an image.

If you’re considering making similar updates to your site, here are some of the learnings I took away from this process.

First a word on SVG browser support SVG

As far as browser support goes, SVG is very well-supported by the browser market; IE 9+, FF 2+, Chrome 4+, etc. For a comprehensive look at browser support, a full support chart is available at caniuse.com.

Deliver SVG first, fallback to PNG

Implementing the change was very straightforward, as there’s really not much to it. The approaches I’ll outline deliver SVG first and fall back to PNG if needed. I’ll cover two implementation use cases:

  1. Using CSS (background-image)
  2. Using HTML (image element)

The CSS approach:

.logo {
background-image: url(logo.svg);
width: 242px;
height: 36px;
background-size: contain;
}

.no-svg .logo {
background-image: url(logo.png);
}

What’s going on here?

We describe the dimensions and background image for the element we’d like to treat like an image, a totally normal approach. The only new thing is making sure the SVG is painted within the bounds of the element by using

background-size: contain.
background-size-contain

This informs the browser that the background image must be completely contained within the element, even if that means some of the element is left uncovered. The opposite approach is when we want to ensure the element is completely covered by the background image, even if it means the image spills out of the element. If that’s what we wanted to do, we’d use:

background-size: cover.

background-size-cover

By hooking into the Modernizr-generated “no-svg” class, we can smartly deliver a fallback image for browsers that don’t support SVG.

Next, HTML technique:

<object width="242" height="36" data="logo.svg" type="image/svg+xml">
<img src="logo.png" /></object>

By using an img element inside an object element, we get an obvious and simple fallback for non-SVG browsers like IE8. Another benefit of using the object element is that all the XML associated with the SVG will get added to the rendered source of the page, allowing you to add event listeners or otherwise manipulate different shapes/paths/nodes.

As an aside, proportions for the image will remain constrained by the width/height attributes. In other words, if you’ve got an SVG image that’s a perfect circle, you’ll need to grow the width and height together to make the circle grow. At no point will that circle become an oval — it will take up as much space as it can while preserving the right proportions.

Internet Explorer and replaced elements

The formal CSS spec has a few rules about how to treat replaced elements that do not have height or width set. In short, IE follows these rules while other browsers don’t – but you might be surprised when your image is displayed at 300×150 in IE. If you’d rather not specify pixel dimensions for your image, you can work around this behavior by setting “width: 100%” on your <object> element with CSS. Sara Soueidan has written a wonderfully comprehensive article about this topic and more.

With an understanding of these two implementation cases, you’re ready to start updating your own images. Now go and make images on your site look great on retina displays!

Leave a Comment