CSS Image Sprites for Retina (HiRes) Devices

Final Product

This is an iframe of a live site. If it is not working for you, click the button for the live preview.
Live Demo Download

Intro

For modern websites icons and graphics have become an increasingly important way to provide visitors with a more visual way to navigate. And as web applications replace more and more traditional desktop applications the use of icons will only increase. But unlike desktop applications anything on the web has to be loaded and having many graphics can slow a site down especially for a site with dozens of buttons. The best way to keep your site loading fast and looking good is to use a CSS Sprite.

CSS Sprites have been around for many years, if you are unfamiliar with them there is a great in depth article here on css-tricks. But the basic premise is that what impacts loading times the most the number of different resources you load on a page. So by combining all your icons into one file you are only loading one resource, thus making your page faster.

Now with the new crop of ultra high definition devices coming onto the market it is important to make sure your site not only continues to load quickly but all your icons and graphics look how you expect. If you do not optimize your graphics they will look like this on ultra high resolution devices:

But with some simple css you can keep the images correct:

Goals

  • Does not add to loading times
  • Delivers the optimum resolution for the users device

Tutorial

To begin we need a solid set of icons. I am going to use a few from my free icon set that you can download here, but any icons or graphics will work. For this tutorial we will be using 5 icons with the final size on the web of 32px by 32px. To create the high resolution icons we need to start with the 64×64 icons.¬†After you have downloaded the icons open up illustrator and create a new file that is 320px by 64px.

Next place the icons you wish to use next to each other until all 5 are on the document. Then go file>save for web and press enter, name the graphic “icons@2x.png”, this is the big resolution version for retina display devices. Next go file>save for web and reduce the size of the image to 50% and name it “icons.png”.

It is now time to get to the coding. Create a new html file named index.html and add the following code

<!Doctype html>
<html>
	<head>
		<title>CSS-Sprite Demo</title>
		<link rel="stylesheet" href="style.css">
	</head>
	
	<body>
		<div class="icons-wrapper">
			<h4>These icons look sharp</h4>
		
			<a href="#" class="icon bar-graph">pie-chart</a>
			<a href="#" class="icon document">document</a>
			<a href="#" class="icon group">group</a>
			<a href="#" class="icon location">location</a>
			<a href="#" class="icon microphone">microphone</a>
		</div>
	</body>
</html>

The html for this demo is very simple, just a series of links that will each have a background icon applied to it. Next create a css file named style.css and add the following style rules to add the icons.

.icon {
	background: url('images/icons.png') no-repeat 0 0;
	width: 32px;
	height: 32px;
	float: left;
	margin: 10px;
	text-indent: -9999px;
}

If you were to view the site now you would see each link has the same first icon from the icons.png graphic. In order to have the correct icons displayed we have to slide the background image to the left in 32px increments using the following code that gets added to the css file.

.document {
	background-position: -32px 0 !important;
}

.group {
	background-position: -64px 0 !important;
}

.location {
	background-position: -96px 0 !important;
}

.microphone {
	background-position: -128px 0 !important;
}

The final step is to add the correct code to load the retina display icons instead of the regualer set. Add this code to the bottom of the css stylesheet.

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
    only screen and (-o-min-device-pixel-ratio: 3/2),
    only screen and (min--moz-device-pixel-ratio: 1.5),
    only screen and (min-device-pixel-ratio: 1.5) {
        .icon {
            background: url('images/icons@2x.png') no-repeat 0 0;
            background-size: 160px 32px;
        }
}

This section uses the new media query from CSS3 to determine the resolution of the users screen and display the icons@2x.png graphic we made. The trick to making it fit correctly is to make the new graphic the same size as the old one using the background-size property.

If you look at your site now you will see each icon is properly displayed and looks sharp regardless of the devices resolution.

Bonus

To add a little style to the demo I added a background image and some CSS3 transitions. Here is the complete code for the demo.

body {
	background: url('images/grey.png') repeat 0 0;
}

.icons-wrapper {
	width: 260px;
	overflow: hidden;
	display: block;
	margin: 150px auto;
	text-align: center;
	-webkit-border-radius: 3px;
	border-radius: 3px;
	-webkit-box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, .3);
	box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, .3);
	background: #ffffff; /* Old browsers */
}

.icon {
	background: url('images/icons.png') no-repeat 0 0;
	width: 32px;
	height: 32px;
	float: left;
	margin: 10px;
	text-indent: -9999px;
	/* CSS3 Transitions */
	opacity: 1;
    filter: alpha(opacity=100);
    -webkit-transition: all 400ms ease;
    -moz-transition: all 400ms ease;
    -ms-transition: all 400ms ease;
    -o-transition: all 400ms ease;
    transition: all 400ms ease;
}

.icon:hover {
	opacity: .4;
    filter: alpha(opacity=40);
}

.document {
	background-position: -32px 0 !important;
}

.group {
	background-position: -64px 0 !important;
}

.location {
	background-position: -96px 0 !important;
}

.microphone {
	background-position: -128px 0 !important;
}

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
    only screen and (-o-min-device-pixel-ratio: 3/2),
    only screen and (min--moz-device-pixel-ratio: 1.5),
    only screen and (min-device-pixel-ratio: 1.5) {
        .icon {
            background: url('images/icons@2x.png') no-repeat 0 0;
            background-size: 160px 32px;
        }

        body {
	        background: url('images/grey@2x.png') repeat 0 0;
	        background-size: 397px 322px;
        }
}

As you can see even a repeating background image can be optimized for a retina display using this technique. The new CSS3 properties for transitions, rounded borders and drop shadows can add those small details that make a site stand out from the crowd. I hope you enjoyed the tutorial and as always if you have anything to say just leave a comment.

Got something to say? Go for it!

 
Read previous post:
Mobile Device Policy & Development in Enterprise

As mobile devices become more powerful and ubiquitous in the workplace companies need to begin supporting and developing for these...

Close