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...
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:
https://www.angrybirdsnest.com/
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:
<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.
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.#container ul {
display: flex;
justify-content: space-evenly;
list-style-type: none;
}
Just a little touch of FlexBox to make it look decent.
#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. 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.
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.