Thursday 16 June 2011

CSS Sprites: What, Why and How?


  • A sprite image is a collection of images put into a single image.

  • A web page with many images can take a long time to load and generates multiple server requests.

  • Using image sprites will reduce the number of server requests and save bandwidth.


The name "sprite" might be a little misleading, because sprites aren't little images like you might be picturing, a sprite is actually one big image. Have you ever seen the CSS technique where the "on" and "off" states of a button are contained within the same image and are activated by shifting the background-position?

Think of CSS Sprites as an extension of that technique. The difference is that instead of just two or three images being combined into one, you can combine an unlimited number of images into one. The origin of the term "sprites" comes from old school computer graphics and the video game industry. The idea was that the computer could fetch a graphic into memory, and then only display parts of that image at a time, which was faster than having to continually fetch new images. The sprite was the big combined graphic. CSS Sprites is pretty much the exact same theory: get the image once, shift it around and only display parts of it, saves the overhead of having to fetch multiple images.

Why combine all those images? Isn't it quicker to have smaller images?

Nope, it's not. Back in the day, everybody and their brothers were "slicing" images to make pages load faster. All that technique did was fool the eye to make it look like the page was loading faster by loading bits and pieces all over at once. Each one of those images is a separate HTTP-Request, and the more of those, the less efficient your page is.

The impact of having many components((i.e. images, scripts, and stylesheets) in the page is exacerbated by the fact that browsers download only two or four components in parallel per hostname, depending on the HTTP version of the response and the user's browser. Our experience shows that reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.

Every single image, whether it's an tag or an background-image from your CSS is a separate HTTP-Request, so you can imagine how quickly those requests can wrack up.

Here is an example from w3schools.com which creates a navigation list using the below sprite image



CSS

<style type="text/css">

#navlist{position:relative;}

#navlist li{margin:0;padding:0;list-style:none;position:absolute;top:0;}

#navlist li, #navlist a{height:44px;display:block;}

#home{left:0px;width:46px;background:url('img_navsprites.gif') 0 0;}

#prev{left:63px;width:43px;background:url('img_navsprites.gif') -47px 0;}

#next{left:129px;width:43px;background:url('img_navsprites.gif') -91px 0;}
</style>

HTML

<ul id="navlist">
<li id="home">
<li id="prev">
<li id="next">
</ul>

Example explained:

* #navlist{position:relative;} - position is set to relative to allow absolute positioning inside it
* #navlist li{margin:0;padding:0;list-style:none;position:absolute;top:0;} - margin and padding is set to 0, list-style is removed, and all list items are absolute positioned
* #navlist li, #navlist a{height:44px;display:block;} - the height of all the images are 44px

* #home{left:0px;width:46px;} - Positioned all the way to the left, and the width of the image is 46px
* #home{background:url(img_navsprites.gif) 0 0;} - Defines the background image and its position (left 0px, top 0px)

* #prev{left:63px;width:43px;} - Positioned 63px to the right (#home width 46px + some extra space between items), and the width is 43px.
* #prev{background:url('img_navsprites.gif') -47px 0;} - Defines the background image 47px to the right (#home width 46px + 1px line divider)

* #next{left:129px;width:43px;}- Positioned 129px to the right (start of #prev is 63px + #prev width 43px + extra space), and the width is 43px.
* #next{background:url('img_navsprites.gif') no-repeat -91px 0;} - Defines the background image 91px to the right (#home width 46px + 1px line divider + #prev width 43px + 1px line divider )

See it working on w3schools.com

No comments:

Post a Comment