Using CSS Image Sprites with the XP Themed TabContainer

I recently blogged about how to create a YUI TabView theme for the AjaxControlToolkit's TabContainer control.  As a follow up to this entry, Peter Kassenaar asked the question:

I just don't quite get how the CSS is able to extract the different (background) images from a single sprite.png file.

I've googled for this, but that didn't help me much. Can you point us to a direction where this is further explained? This would give me the perfect opportunity to clean up my /images folder on the various themes of a project...

In the YUI theme I created, I used a single sprite image and used CSS to pinpoint the location within the sprite for the background image of the tab panel header's.  Peter is asking how I did this.  To be honest, I just reverse engineered the CSS style attributes from Yahoo!'s demo site along with the exact same sprite image (which includes many extra images that the YUI themed TabContainer doesn't use).

While I have read about using CSS sprite's before, I haven't actually implemented it (or seen it implemented) on any of the project's that I have worked on.  I was curious in learning more about the technique, so I thought it would be interesting to convert the default XP TabContainer theme to use a sprite image (it currently makes use of 11 different individual images). 

Even better, a side effect of this exercise would be getting rid of that flicker when the first time a tab is rolled-over (the image on the left shows a screen shot of what happens on the first roll-over, the screen shot on the right shows what it is supposed to look like).  This flicker occurs because the roll-over image isn't fetched until the first time the user mouse's-over the control.  The first time this happens, the image is fetched and cached so it will be available for subsequent roll-overs.

     

Live Demo | Download

What are CSS Sprites?

From Pixy's Fast Rollovers

When using CSS image rollovers, two, three, or more images must be loaded (and often be preloaded for best results). We've got one image for each state (normal, hover, active, visited etc). Putting all states into one image makes dynamic changes faster and requires no preload.

I used the following links to learn more about CSS Sprites

Creating the Sprite Image

My first step was to create the sprite image.  I have Paint Shop Pro, so my first approach was to try to manually create the sprite myself using Paint Shop Pro.  Unfortunately this was tedious and time consuming so I was really excited when I stumbled across this link: CSS Sprite Generator (thanks mhinze for the pointer to this site)

The CSS Sprite Generator page is a nice tool that allows you to automate sprite image generation along with the corresponding CSS.  Just what I needed! 

So my next step was to zip up the XP theme images, upload them to the web site so I could build my sprite.  After uploading my images and filling out them form, I clicked the 'Create Sprite Image & CSS' button and saved the generated image to my local folder.

Here is a link to the sprite this tool generated for me.  Below is a crude screenshot of part of the sprite.  To the right is the negative offset of each of the images.

Create the CSS

After you click the 'Create Sprite Image & CSS', the page allows you to download the image and it also display's the offset's into the sprite for each of images.  So for our XP tab theme sample, the tab.gif image can found at offset -5px, the tab-hover-left.gif image is located at offset -135px and the tab-left.gif image is at -187px.  Perfect. 

So now I have the sprite image and the X offset's into the sprite for all of the original images.  Now I am ready to put it all together with a new XP theme I called 'xpsprite-theme'.  The CSS classes for this theme are located below.  Notice all I did was modify the original xp tab theme and reference the sprite image using the offset.  Now to use this new theme, just include the CSS along with the sprite image and set the CssClass property to: ajax__tab_xpsprite-theme.

/* ajax__tab_xpsprite-theme theme */
.ajax__tab_xpsprite-theme .ajax__tab_header 
{
    font-family:verdana,tahoma,helvetica;
    font-size:11px;
    background:url(img/xp_sprite/tab-line.gif) repeat-x bottom;
}
.ajax__tab_xpsprite-theme .ajax__tab_header .ajax__tab_outer 
{
    padding-right:4px;
    background:url(img/xp_sprite/sprite.png) no-repeat right -213px;
    height:21px;
}
.ajax__tab_xpsprite-theme .ajax__tab_header .ajax__tab_inner 
{
    padding-left:3px;
    background:url(img/xp_sprite/sprite.png) no-repeat left -187px;
}
.ajax__tab_xpsprite-theme .ajax__tab_header .ajax__tab_tab
{
    height:13px;
    padding:4px;
    margin:0;
    background:url(img/xp_sprite/sprite.png) repeat-x left -5px;
}
.ajax__tab_xpsprite-theme .ajax__tab_hover .ajax__tab_outer 
{
    background:url(img/xp_sprite/sprite.png) no-repeat right -161px;
}
.ajax__tab_xpsprite-theme .ajax__tab_hover .ajax__tab_inner 
{
    background:url(img/xp_sprite/sprite.png) no-repeat left -135px;
}
.ajax__tab_xpsprite-theme .ajax__tab_hover .ajax__tab_tab 
{
    background:url(img/xp_sprite/sprite.png) repeat-x left -109px;
}
.ajax__tab_xpsprite-theme .ajax__tab_active .ajax__tab_outer 
{
    background:url(img/xp_sprite/sprite.png) no-repeat right -83px;
}
.ajax__tab_xpsprite-theme .ajax__tab_active .ajax__tab_inner 
{
    background:url(img/xp_sprite/sprite.png) no-repeat left -57px;
}
.ajax__tab_xpsprite-theme .ajax__tab_active .ajax__tab_tab 
{
    background:url(img/xp_sprite/sprite.png) repeat-x left -31px;
}
.ajax__tab_xpsprite-theme .ajax__tab_body 
{
    font-family:verdana,tahoma,helvetica;
    font-size:10pt;
    border:1px solid #999999;
    border-top:0;
    padding:8px;
    background-color:#ffffff;
}

That's it. Enjoy!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/71

Comments


Posted by: gokhan demir on October 1, 2007 12:00 AM

very cool matt !

Hi Matti,

Awesome followup, this post. Thanks for the other links in the article. Like you - after reading the ALA-post- I first struggled with a graphics design tool (MM Fireworks 8 in my case) to design and calculate my own sprite graphics, but this was quite tedious and error prone.

Oh yes, one pixel offset to much or to little *does* make a huge difference in the end user experience...

I therefore especially like the pointer to the CSS Sprite Generator, thanks a bunch!

Keep it up,
Regards.
Peter.

PS. Have you considered using Techsmith Snagit 8 as a screen capture tool? They provide nice little balloons and arrows etc. out of the box to point to the various places in a screenshot. And they have a neat plugin for Visual Studio now also...

@Peter
Thanks for the feedback. I will check it out.

Matt.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • gokhan demir wrote: very cool matt ! ...
  • Peter Kassenaar wrote: Hi Matti, Awesome followup, this post. Thanks for the other links in the article. Like you - after ...
  • Matt Berseth wrote: @Peter Thanks for the feedback. I will check it out. Matt. ...