How To Use CSS Sprites: An Ingenious Way of Reducing Page Loading time

February 20th 2020
Author profile picture

@tirthajyoti-ghoshTirthajyoti Ghosh

Preparing to be The Change

LinkedIn social iconTwitter social icongithub social icon
Imagine you have six images on your home page. You might proceed with loading the images separately. After all, they are six different images and to be used in six different places. And you might be right ... from your perspective. You also know that loading six different images will force the browser to make six different HTTP requests to the server. And each time it makes a request, a few milliseconds gets added to your page loading time. That's bad news if you have fifty images.
So how can you reduce the loading time of images? Umm.... what if we could load all the images together at once? That's right. We can load all the images together instead of requesting each of them multiple times. But how? Here comes the CSS Sprites. First of all...

What is a sprite?

The term "sprites" comes from a technique in computer graphics, most often used in video games. 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.
A typical Sprite looks like this:
So how do we gain this superpower? By taking advantage of
background-image
and
background-position
property in CSS and some foresight with a pinch of arithmetic.
Take a look at this image:
Credit: smtusa.com
We are going to turn that into this:

The markup skeleton:

<div id="container">
  <ul>
    <li class="item1"></li>
    <li class="item2"></li>
    <li class="item3"></li>
    <li class="item4"></li>
  </ul>
</div>
One container with an unordered list within.

Writing "CSS Sprite Example" with
backround-image
:

#container {
  background: url("csssprites.jpg") no-repeat 0px 12px;
  height: 0;
  padding: 30px;
}
By using the
background
shorthand property I set the background-image as "csssprites.jpg",
background-repeat
to "no-repeat" and most importantly
background-position
to "0px 12px" which means I am telling the browser to move the image 0px horizontally and 12 px vertically. By setting the
height
to 0, the rest of the image will not be visible. A bit of padding to give it some breathing room.

Making the list horizontal:

#container ul {
  display: flex;
  justify-content: space-evenly;
  list-style-type: none;
}
Just a little touch of FlexBox to make it look decent.

Set the dimensions of image container:

#container li {
  width: 240px;
  height: 58px;
}
The
li
elements will hold the images, so setting its dimensions will allow us to control how much of the image is visible.

Positioning the images with some math:

li.item1 {
  background-image: url('csssprites.jpg');
  background-repeat: no-repeat;
  background-position: -55px -42px;
}

li.item2 {
  background-image: url('csssprites.jpg');
  background-repeat: no-repeat;
  background-position: -55px -100px;
}

li.item3 {
  background-image: url('csssprites.jpg');
  background-repeat: no-repeat;
  background-position: -55px -158px;
}

li.item4 {
  background-image: url('csssprites.jpg');
  background-repeat: no-repeat;
  background-position: -55px -216px;
}
Here I am telling the browser to set the
background-image
of the
li
elements to "csssprites.jpg" and not to repeat them with
background-repeat: no-repeat
. The magic happens with
background-position
property.
If you notice closely, the first value of each
background-position
of each
li
is "-55px". This means the browser will move the image 55px horizontally to the left.
background-position
is based on the cartesian coordinate system. So if you want to move the image to the left you apply negative values and if you want to move the image to the right apply positive values. Similarly, moving to the top is positive and down is negative.
In order to position "list item 1" in
li.item1
, I moved the image down by 42px(the height of "CSS Sprite Example" is 42px). Since all the "list item"s are on top of each other, we have to move down the image by their height, which is "58px", for each subsequent
li
elements. For "list item 2" to be visible in
li.item2
, I moved the image down by "100px"(42px + 58px), and similarly "158px"(100px +58px) for
li.item3
and "216px"(158px +58px) for
li.item4
.
Think of your image container as a magnifying glass and the image as the paper. In this case, you move the paper to view the portion of the image you want to see through the magnifying glass.
Here is the live demo.
Originally published in this GitHub repo.

Compendium:

That's it. Simple yet clever. CSS sprites are not a new concept. In fact, Google and YouTube used this technique before they had a full-on makeover. Popular sites like Xing, Amazon, Yahoo, etc. use CSS sprites.
This is just the beginning. There is no limit to what you can do with CSS sprites. The possibilities are endless. Here are some wonderful resources to get your mental gears turning:
So what are you waiting for? Fire up your imaginations and jump right in.

Comments

Tags

The Noonification banner

Subscribe to get your daily round-up of top tech stories!