back to top

info(at)sypo.uk01539 741461

Responsive Image Sprites Using Only CSS

Posted on 1st November, 2018

image-sprites-full.jpg

By Mark Syred. Difficulty level: Medium

Before I launch into the explanation of how to achieve this, I'd just like to explain what image sprites are. If you ever played Horace Goes Skiing, Lotus Esprit Turbo Challenge (am I showing my age?) or pretty much any computer game in the 80's or 90's, you will have come across them. What they are is a collection of smaller images put together into one larger image file that the computer game's code then selects parts of depending on what the user is doing in the game. This gave the illusion of movement or driving along a road. The use of sprites saved a lot on the load on the computer.

Sprites in web-design work in a very similar way. For a working example of one you need look no further than the social media links beneath this paragraph. Click on them, if you like, and you'll be taken to our Twitter, Facebook and YouTube accounts. Right click on any and select 'View Image' and you will see the sprite in full, displaying each of the icons and their hover state. Using only one sprite for all three of the social media links means there is only one round trip required by the browser to fetch all the, 'different,' icons and their hover states.

SYPO on twitter SYPO on YouTube SYPO on facebook

Search the internet for how to add image sprites to your site, and you'll find several different methods. One key advantage with this one is that you can easily add titles and alt tags to the images (great for SEO), and, crucially, all that is required is a bit of CSS.

Firstly the HTML.

Almost all that is needed is a containing div, three links, and one hyperlinked sprite, referenced three times:

<div id="spritelist">
    <a id="twitter" href="https://twitter.com/sypo_uk">
        <img src="/themes/sypo/images/sypo-social.png" alt="SYPO on twitter" title="Follow us on Twitter">
    </a>
    
    <a id="youtube" href="https://www.youtube.com/channel/UCTJg0UBpnb5_Qi_0NDm4HgQ">
        <img src="/themes/sypo/images/sypo-social.png" alt="SYPO on YouTube" title="Watch with YouTube">
    </a>
    
    <a id="facebook" href="https://www.facebook.com/SellYourProductsOnline/">
        <img src="/themes/sypo/images/sypo-social.png" alt="SYPO on facebook" title="Like us on Facebook">
    </a>
</div>

Of course, if you were to use this for your own site, you would point the links to your own social media pages, or whatever pages you wanted and alter the alt and title tags. You could use image sprites for navigation, for example.

The key part of the HTML that interacts with the CSS to make the sprites work is as follows:

<a id="twitter" ><img src="/themes/sypo/images/sypo-social.png"></a>

As a minimum, there needs to be an a href that has a target and an id or class, and there needs to be an image, which itself needs NO id or class.

Now for the CSS

As with any CSS that I have written for this site, it is mobile first followed by specified breakpoints for the various screen sizes/orientations. I'll give you it all and then explain a few bits:

#spritelist {
    padding: 5%%;
    background: #eaeaea;
    margin: 15px auto 20px;
}

#twitter, #youtube, #facebook {
    width: 20%;
    height: 0;
    padding-bottom: 20%;
    overflow: hidden;
    display: inline-block;
}

#twitter {
    margin: 0 5% 0 8%;
}

#youtube {
    margin: 0 5%;
}

#facebook {
    margin: 0 8% 0 5%;
}

#twitter img, #youtube img, #facebook img {
    width: 300%;
    border: none;
}

#twitter img {
    margin: 0;
}

#youtube img {
    margin: 0 0 0 -100%;
}

#facebook img {
    margin: 0 0 0 -200%;
}

#twitter: hover img, #youtube: hover img, #facebook: hover img {
    width: 300%;
}

#twitter: hover img {
    margin: -100% 0 0 0;
}

#youtube: hover img {
    margin: -100% 0 0 -100%;
}

#facebook: hover img {
    margin: -100% 0 0 -200%;
}

@media screen and (max-width: 479px)  {
    #spritelist {
        width: 100%;
    }
}

@media screen and (min-width: 480px) and (max-width: 799px)  {

    #spritelist {
        width: 85%;
    }
}

@media screen and (min-width: 800px) and (max-width: 1100px)  {

    #spritelist {
        width: 75%;
    }
}

@media screen and (min-width: 1101px) {

    #spritelist {
        width: 60%;
    }
}

The code to manage the sprites themselves doesn't change at all across all the screen sizes. What does alter is the size of the containing div. To help with the responsiveness, this is always set to a percentage of the screen-width as follows:

@media screen and (max-width: 479px)  {
    #spritelist {
        width: 100%;
    }
}

@media screen and (min-width: 480px) and (max-width: 799px)  {

    #spritelist {
        width: 85%;
    }
}

@media screen and (min-width: 800px) and (max-width: 1100px)  {

    #spritelist {
        width: 75%;
    }
}

@media screen and (min-width: 1101px) {

    #spritelist {
        width: 60%;
    }
}

To set up the size of each icon on the page, the following code is used:

#twitter, #youtube, #facebook {
    width: 20%;
    height: 0;
    padding-bottom: 20%;
    display: inline-block;
}

As each icon is identically sized, the ids for each icon are listed together:

#twitter, #youtube, #facebook

The width of 20% sets the icons to be 20% of the containing div. This part ...

height: 0;
padding-bottom: 20%;

... forces the height to respond to the width of the screen. The height should be set to 0, but to find the correct padding-bottom, requires a bit of calculating. In this case, as the icons are square, the padding-bottom matches the width exactly. Were the icons rectangular, where the height was half the width, then so too would the padding-bottom be. So, the padding-bottom would be 10%. If the height were double the width, the padding-bottom would be 40%.

The margins for each of the icons differ slightly, so:

#twitter {
    margin: 0 5% 0 8%;
}

#youtube {
    margin: 0 5%;
}

#facebook {
    margin: 0 8% 0 5%;
}

As the width of the sprite used to display the icons is three times the width of what you want the user to see, both in the hover state and at rest ...

#twitter img, #youtube img, #facebook img {
    width: 300%;
    border: none;
}

#twitter: hover img, #youtube: hover img, #facebook: hover img {
    width: 300%;
}

The margins of the icons, set by their ids, that determines which part of the larger sprite is displayed, both when hovering and at rest:

#twitter img {
    margin: 0;
}

#youtube img {
    margin: 0 0 0 -100%;
}

#facebook img {
    margin: 0 0 0 -200%;
}

#twitter: hover img {
    margin: -100% 0 0 0;
}

#youtube: hover img {
    margin: -100% 0 0 -100%;
}

#facebook: hover img {
    margin: -100% 0 0 -200%;
}

The negative margins 'pull' the correct part of the sprite into view. Percentages are used to keep it all responsive. And the percentages were calculated using the method outlined in the image below:

And, finally, to ensure that only the part of the sprite that is required is shown at any one time, the rest of it is hidden:

overflow: hidden;

This website uses cookies to deliver the best experience whilst browsing. More info