Image sprites using CSS only

Posted by Stefan Kecskes on Tuesday, August 4, 2015

What are image sprites and why should I use them?

Image Sprite

Web pages these days have many images. They are also called multimedia rich web pages. It may take a long time to load all of them. Each image means a server request from browser. Did you know that browsers these days download concurrently only 6 resources? That means that browser will start to download next resource only when one of the resources is fully downloaded and the slot is empty for next resource. Browser will do the following, each time when the browser looks into the list of resources needed to display the web page:

  • wait for the free slot - Time the request spent waiting before it could be sent.
  • Proxy negotiation (if applicable) - time spent negotiating a proxy server connection.
  • DNS lookup - time spent performing DNS lookup. Every new domain on a page requires a full roundtrip to do the DNS lookup
  • setup initial connection - TCP handshake
  • SSL (if applicable) - Time spent completing a SSL handshake
  • send the HTTP request to get the resource - Time spent issuing and sending the network request.
  • wait for the response from the server - Time spent waiting for the initial response (Time To First Byte)
  • content download - Time spent receiving the response data

As we can see there is a lot going on in the background. Lets just assume that we have some images which are displayed on each page, images like “Read more” or social media images and images for hover effect on social media images, etc… Each of these images will be displayed in browser only after the browser makes all the steps above for each of them. The idea behind image sprites is that we can join all these images into one image sprite. Using image sprites will reduce the number of server requests, reduce waiting time and save bandwidth.

Apple pie recipe

Basically we used to prepare apple pies this way

Recipe from Internet

    Here is money for 1st apple
    Go to shop
    Buy the 1st apple
    Come back from the shop
    Waiting while you bring the 1st apple
    Add the 1st apple to pie
    Here is money for 2nd apple
    Go to shop
    Buy the 2nd apple
    Come back from the shop
    Waiting while you bring the 2nd apple
    Add the 2nd apple to pie
    Here is money for 3rd apple
    Go to shop
    Buy the 3rd apple
    Come back from the shop
    Waiting while you bring the 3rd apple
    Add the 3rd apple to pie
    ...
    Bake and display the apple pie 

I shortened the recipe with three dots, because otherwise it would be very long, but surely you get the idea and now I’m going to show you how to prepare it my way

Recipe by Stefan Kecskes

    Here is money for apples
    Go to shop
    Buy the apples
    Come back from the shop
    Waiting while you bring the apples
    Add the apples to pie
    Bake and display the apple pie 

They both taste the same, but the second one will be prepared faster. Now, I will show you how to do same improvement in web development using simple image sprite for social media icons.

Creating image sprites

We will need to collect all the images we want to use. To make our image sprite example simple we will use all images with same size, but in real world you can create image sprites with different sized images. This is image sprite I will use in this example.

social media icons

HTML markup

Now we make some HTML markup. We will create links to social media pages, and they will contain image. I also add spacer, which is there only to preserve the size. The image will never get smaller than spacer, even on responsive designs.

	<div>
		<a href="#facebook" class="spritelink" title="See me on facebook">
			<div class="spacer"></div>
			<img src="/images/social.png" alt="See me on facebook" class="sprite" />
			<!-- the first sprite doesn't need facebook class because this the default view of sprite -->
		</a>
		<a href="#twitter" class="spritelink" title="Follow me on twitter">
			<div class="spacer"></div>
			<img src="/images/social.png" alt="Follow me on twitter" class="sprite twitter" />
		</a>
		<a href="#youtube" class="spritelink" title="Watch my videos on youtube">
			<div class="spacer"></div>
			<img src="/images/social.png" alt="Watch my videos on youtube" class="sprite youtube" />
		</a>
		<a href="#pinterest" class="spritelink" title="See my life through images">
			<div class="spacer"></div>
			<img src="/images/social.png" alt="See my life through images" class="sprite pinterest" />
		</a>
		<a href="#blogger" class="spritelink" title="Read my thoughts on blogger">
			<div class="spacer"></div>
			<img src="/images/social.png" alt="Read my thoughts on blogger" class="sprite blogger" />
		</a>                        
	</div>

Still simple, yeah? Now comes the magic.

CSS styling

Here comes the CSS we will need to apply on our HTML. Please read the comments next to styling so you better understand, why we used styles and what they do.

    .spritelink {
    	display: inline-block;	/* each link must behave like inline block instead of default inline only */
        position: relative;		/* container must be relative so that absolute positions are calculated from here */
        overflow: hidden;		/* hide overflowing parts of image sprite*/
        max-width: 64px; 		/*Set the max-width to the width of your individual sprites:*/
        margin-left: 3px;
        margin-right: 3px
    }
    
    .spacer {
        width: 64px; /* the spacer will preserve the place for image to be always at least 64px wide */
        height: 64px;
    }
    
    .spritelink .sprite {
        position: absolute;	/* we are going to get absolute posititon from image from top left corner */
        top: 0;
        left: 0;
        max-width: none;	/* width can vary */
        max-height: 200%;	/* but the height will take always 200% of available space - first row on image sprite */
    }
    
    .spritelink .sprite.twitter {
        left: -100%;	/* second image in first line */
    }
    
    .spritelink .sprite.youtube {
        left: -200%;	/* third image in first line */
    }
    
    .spritelink .sprite.pinterest {
        left: -300%;	/* fourth image in first line */
    }
    
    .spritelink .sprite.blogger {
        left: -400%;	/* fifth image in first line */
    }
    
        
    .spritelink .sprite:hover {
    	top: -100%	/* On mouse hover go 100% down from the first line, so show the second line of image sprite */
    }

Image sprites in action

Here we can see the working demo of the code above. As you can see the social icons are displayed like different images, even when they are coming from one image only.

See me on facebook
Watch my videos on youtube
See my life through images
Read my thoughts on blogger

Conclusion

I have showed you how we can replace 10 images with only one, which saves us lot of HTTP requests, waiting time and by optimizing image sprite also save bandwidth. Then I showed you simple sprite HTML markup and CSS styling. In the final result, the social media images looks like they are separate images, but in fact they are all only one optimized image. As far as I know, this solutions is compatible in all current browsers and mobile devices (August 2015) as we are using only simple CSS 1.0 styles.

If you have learned something new or need an advice, please let me know. I will be happy.