Social Menu Icons Using Sprites

Have you ever used yslow, or some other method of evaluating your site load speed? If you have you probably got a warning that using sprites will speed up your site by reducing server calls for individual images. If you are like me, the first time you saw that you were thinking about how you might go about trapping woodland faeries, and once you catch them, how do you upload them to your site?

Yeah, turns out sprites are images that have several other images built in. This lets you load one image instead of 10. The tricky part is, how do you do that?

I setup a ton of possible social icons for the header in my Fluid Theme. By “a ton” I mean over 50 icons. While it is unlikely anyone would try and use all 50 icons, it is certainly possible that someone might use 5 or 6. Fluid only has 12 images not counting the post formats, which have to be handled differently, so making individual images really would add up.

Let’s look at how I did this.

Make your sprite image

This is the image I’m using in fluid (click for full size).

I started by doing the math on my largest icon size and making a grid to layout where the images would have to fit using the guides in Photoshop. The icons should be as close as possible but leave room so even large icons will fit near each other without invading the space. I could have probably squeezed the images a tiny bit closer, but I like a few px as a “fudge” factor so I can tweak the exact placement of the icon. Notice the vertical space between the rows compared to the horizontal space between the columns, that’s to allow more vertical adjustment.

Enough on making the image,

Setup the CSS

There are two approaches to handling the class for the CSS. I prefer to use two classes instead of one, because it makes the CSS much cleaner. When working with 50+ icons, clean CSS is important. So instead of using a class social-aim, I use class social aim. This means that you have to type in social and aim as two separate words in the custom menu class. This is just as easy as typing social-aim, but really makes a big difference in the CSS.

Let me show you what I mean. The “social” class will cause these CSS rules to work

#header ul.menu li.social {
    background: none repeat scroll 0 0 transparent;
    margin: 5px;
}

#header ul.menu li.social a {
    background: url("images/social-header.png") no-repeat scroll 0 0 transparent;
    display: block;
    height: 48px;
    width: 48px;
    text-indent: -9999px;
    padding: 0;
}

The first rule clears the background on the li (the default CSS has a background on li) and gives the icons some space using the margin. The second rule sets the background to use the social-header.png file, does not allow the background to repeat and sets the default position. It also sets display:block, which allows the height and width values to work. Then it clears the text by using the text-indent:-9999px and sets the padding to 0. Those rules automatically get added to all the menu items with the social class. This means I don’t have to apply those rules to each of the possible icons. With 50+ icons, this saves over 300 lines of code.

Tell the browser which part of the image to use

This is the real magic for using sprites. You have an image, you setup the base CSS, but now you have to figure out what part of the image to use. If you setup your grid using math before, like I did, then you can get the rough math to start with. You need negative values for the background position since you are defining where the top and left edges should start relative to the edge of the container. Here are a few examples from the fluid style sheet.

#header ul.menu li.aim a {
    background-position: 0 0;
}

#header ul.menu li.aim-alt a {
    background-position: -48px 0;
}

#header ul.menu li.behance a {
    background-position: -95px 0;
}

#header ul.menu li.dailybooth a {
    background-position: 0 -49px;
}

#header ul.menu li.delicious a {
    background-position: -48px -49px;
}

#header ul.menu li.dropbox a {
    background-position: -95px -49px;
}

#header ul.menu li.sharethis a {
    background-position: 0 -104px;
}

#header ul.menu li.formspring a {
    background-position: -48px -104px;
}

#header ul.menu li.forrst a {
    background-position: -95px -104px;
}

That is all you have to define for the various other classes if you setup your social class right. I manually change each item in firebug to get an idea of how it looks, and tweak if needed. If everything is done perfectly in your image, then you just need to know the edge of your columns and rows.

Want more examples? Go check out my fluid theme and see how I did the rest of the icons.

Sprite Me

I realized I forgot to mention this when someone retweeted the post. If you already have a lot of images on your site, or prefer to skip some of the steps, you can get a big head start using SpriteMe. You have to setup your CSS like normal, using individual images and define the repeat rules correctly. Then run the bookmarklet from SpriteMe to merge images and get CSS that you can use as a starting point. However, I prefer to start by building my sprites/css correctly as the code and image can be condensed more efficiently and I don’t like working twice.

Do you use social icons in your themes? If so, how you used sprites or individual icons and do you setup the image and other CSS rules individually or do you use two classes to simplify the CSS?

Comments

  1. Overall, it’s an excellent technique, and I’m happy you’ve taken the time to write a tutorial.

    Instead of using two classes on each list item, you can use one class on the unordered list element, and then unique classes on the list items, giving cleaner markup.

    This then extends to the CSS. If your ul class is social-icons, then each selector can be cut down to just .social-icons>.twitter {} – the use of the child selector instead of the descendent selector improves CSS performance, while the lack of the id and oh contextual selectors makes the code more modular, reusable, and gives a lower specificity score.

    In terms of the sprite image, having all the images in a single vertical column would likely save bytes, and make calculating the background position easier, since you’re only working in one dimension except for the tiny tweaks.

    • Gary,

      Thanks for the comments, I disagree with using the UL class though, since this forces all items in the menu to use the markup, this method allows menu items to be mixed and matched as needed, so the end user could have a couple page menus, then the social icons, if that is what they want.

      That’s the tricky part in handling markup for end users that might do things differently versus doing markup for individual sites where you are handling the only possible usage.

  2. Its a very nice tutorial.

    I wanted to used the social header image in this page in one of my commercial projects. Can I do that? I will surely include your name in the credits.