CSS Sprites with Background Positioning

html-templates

There’s nothing more common than hover states to give your website some life. The user comes to your site, scrolls over an image with their mouse cursor, and the image changes. That’s it. While I spent most of 2012 learning backend programming with Ruby on Rails, I’m only recently spending more time improving my frontend development skills. Earlier this week, I needed to implement the hover state effect so I researched what the best practice was. All of the tutorials and tips I could find were unclear, outdated, or plain confusing so I decided I’d write my own.

We’re currently in development on some new things for Uncover and on one page we have an image that we want to change when a user rolls their mouse cursor over it. Here’s the image:

preview-1

When a user rolls over it, we want it to change to this:

preview-2

Let’s look at how I implemented this earlier today. I wanted to use what’s known as Image Sprites in CSS. That’s a collection of images on a single image, which helps reduce load times as the user only needs to make a single request to the server rather than multiple requests for each image.

Here’s a look at the sprite I created:

preview-3

You can see that I have one image neatly aligned on top of the other. Both images are the same height and width.

In my example, I want the user to be able to click the image to go to a new page of the website. Note that it’s just a standard HTML link with a class of preview. Here’s the HTML I used:

Here’s the CSS that goes along with the HTML:

.preview {
display: block;
margin: 0px auto 20px;
width: 305px;
height: 321px;
background: image-url(‘preview-3.png’) 0 0 no-repeat;
}

.preview:hover {
background-position: 0 -321px;
}

How this works is that the image on top is the image I want to display before hover. That’s why the background is set to top. Then on hover I want the image below to be displayed, so that’s why the background-position is set to bottom. It’s that simple.

Spencer Fry

I’m a 29 year old entrepreneur. A Business Guy turned Programmer. Co-founder & CEO of TypeFrag ('03 - '07), Carbonmade ('07 - '11) and currently Uncover ('12+). Uncover is everything you need to start and run an employee recognition program for your company. My hobbies are squash, soccer, cooking, music, and art. You should follow me on Twitter.

Comments

10 comments on “CSS Sprites with Background Positioning

  1. I think I would have used a :after pseudo class to apply the transparent background, just to avoid spending time in Photoshop creating sprites.

    Then possibly use the Opacity: 0.5; or maybe turn the icon into a font to control the colour using rgba.

    Hard to say without actually mocking up an example though :D

  2. OK, so I have a really great Idea for an APP. I really believe it will be very successful. Now … Who do i contact? what do I do ?

  3. I have to agree with Mike on this one. While sprites are useful, it’s an extra http request, and the previous year of browser advancement has allowed us many other ways to render the hover changes we need.

    I would suggest using a pseudo element (http://css-tricks.com/pseudo-element-roundup/) to render the changes, an iconfont seems a bit heavy handed if this is the only hover effect of the type, but if it’s something that you’ll need across many different icons, it would be worth looking into.

    Great article though! You’re right about the lack of info out there about sprites. especially about current sprite techniques.

  4. Pro tips:

    1. Include a 1-pixel transparent bleed around each of your sprites. For example if you’re creating a block of 16×16 pixel sprites, make them 18×18. The reason for this is that some browsers “incorrectly” handle sprites when zoom != 100%. If you don’t include a transparent border and the user zooms in or out, they may see adjacent sprite images bleed into your target image.

    2. If you’re designing @2x images for high density displays (eg “retina” or any new mobile device)… and you should be… you’ll need to use the CSS background-size style to get the effect you want. This is a different topic, but probably useful to mention.