CSS Sprites2 - It’s JavaScript Time

by Dave Shea

86 Reader Comments

Back to the Article
  1. I’ve never been a big van of javascript “frameworks” in general, since they seem an extra layer of abstraction on an already simple scripting language.

    For those unwilling to snuffle through script, I have something similar that can be applied through a class-name in my classBehaviours collection: http://www.classbehaviours.com/details.php?id=cosmetic-mouse-interaction

    I didn’t take the “sprite” approach though, my “animated class-name” example could be adapted for that.

    Copy & paste the code below to embed this comment.
  2. @ Joy Budiman: Here is a link you should find helpful. It was posted on Google’s Webmaster Help forum and linked too from Google’s Webmaster Blog a few days ago. “Google’s Clarification on Hidden Text”:http://groups.google.com/group/Google_Webmaster_Help-Indexing/msg/d6aa4da7a87e5230

    @*Maurice van Creij*: The major advantage of jQuery, for me, is that it’s pre-tested to work in all of the popular browsers. I personally don’t know enough about Javascript to know how to fix all of the cross-browser problems that may occur, however, my clients are requesting more and more Ajax from me (a front-end developer). jQuery gives me fast turn-around and allows me to keep my attention on other things, while keeping me from having to outsource parts of my work to a Javascript expert.

    Copy & paste the code below to embed this comment.
  3. I was trying to do something similar recently but which added an additional hurdle: using transparent PNGs. I finally figured out a way to get them to display properly as background images in IE6, only to find out that you can’t change their background position, rendering the whole concept of CSS sprites useless.

    Any ideas on how to get around this? Could the same method work with individual images set as background images for each list item?

    Copy & paste the code below to embed this comment.
  4. It’s worth emphasizing that this technique degrades gracefully; if you disable Javascript, the mouseover effect still works, albeit without animation.

    Copy & paste the code below to embed this comment.
  5. I have a hard time figuring out the benefits of the CSS technique used to define the current element. Using a current class on the li would greatly simplify the JS and the CSS a bit too.

    Is there a particular reason for this structure or is it an IE 5 inheritance ?

    Copy & paste the code below to embed this comment.
  6. CSS Sprites is a nice yet extremely hard to manage menu effect.  But this is not CSS Sprites2.  I’ve played with this method before, and it has little relation to CSS Sprites.  Seems a little audacious to call it that.

    That said, jQuery rocks, and I’m always glad to see it get some love!  :)

    Copy & paste the code below to embed this comment.
  7. Great technique, useful especially when you need jQuery for other tasks too.

    I modified the script a little to suit my needs adding focus() and blur() events to make it more usable for keyboard navigation. That was the only thing I was missing in the example

    Copy & paste the code below to embed this comment.
  8. Took a look at your article and decided to go ahead and make it happen. With some tweaking of the ‘sprite’ I managed to get the same image to function as both the unfocussed and focussed tab, and the various images that sit on top of it. You can see it here:
    http://www.partyark.co.uk

    Thanks for the inspiration!

    Copy & paste the code below to embed this comment.
  9. Perhaps somewhat off topic, but why is it that so many love to quote Jeremy Keith and unobtrusive scripting, while at the same time missing the boat by ignoring the principles of graceful degradation or “Hijax”?
    From an accessibilty perspective, what’s the difference between refering to a plain “#”  or using inline javascript in navigations? While in the past, it might have been a bit of a struggle to hijax URLs, but the “preventDefault” method in jQuery (and MooTools …) has made it so easy. Can’t we just use it?

    Copy & paste the code below to embed this comment.
  10. I personally don’t find the one that changes colors particularly useful, and I find the animations annoying. If anything, this slows me down, not a good thing for the web.

    For this to be Section 508 accessible, there needs to be a way to turn the animations off.

    Copy & paste the code below to embed this comment.
  11. This is a bit of an aside, but what happens when images are turned off. As far as I can tell the whole menu disappears. Are we assuming with the css sprites that users who disable images will also disable css.

    You mentioned in your original article that there was no known way around this. Has anything changed? And do you see this as an issue?

    Copy & paste the code below to embed this comment.
  12. Great article, Dave. I might even read it again just to pound it into memory. Although I noticed one slight bug: your :focus lacks the removal of a border. If you click (and hold) on an element in Firefox 3.0.1 (not sure of others) you see a read border around the element, and when released—as the focus still holds—a blue border is shown. Obviously a bit tacky for the perfectionists in the group.

    Great article either way, perhaps soon these sorts of tricks can just remove the useless flash objects from the web, and only keep the truly unique ones.

    Copy & paste the code below to embed this comment.
  13. Thanks for the tutorial, great effect… however, it appears broken in IE6. Has anybody gotten this to work in that browser?

    Copy & paste the code below to embed this comment.
  14. very good article for beginners and experienced worth to read and recommend

    Copy & paste the code below to embed this comment.
  15. Interesting technique! I have been toying with it for a while, and am now using it in the website I’m currently working on. However, I didn’t want to rely upon a large JavaScript framework, so I actually wrote my own custom animation code. It condenses to not much more than 3K. (Just over 4K uncondensed.) I’ve went some way into abstracting it and adding some more advanced functionality, and it doesn’t look like it will go over 8K uncondensed; it’s currently at about 4.5K. If I can make it easier to drop into place—the trade-off for conciseness is complexity, in this case—would anyone be interested?

    Copy & paste the code below to embed this comment.
  16. Not sure if it’s your script or CSS, Dave, or if it’s just the ALA’s lack of support, but keyboard support should be added. I can’t of a reason why it would be left out.

    @Bruce Lawson, re: animated GIFs. I tried that (“see experiment here”:http://green-beast.com/experiments/css_flashy_links.php) and it works nicely (don’t use a looped animation solves the looping problem), but only in Firefox. It seems to behave differently in all browsers, thus Dave’s solution is better (albeit lacking in accessibility).

    Copy & paste the code below to embed this comment.
  17. I am using this technique with transparent png’s as background images. It works fine in FF, Safari and Opera, but not in IE7.

    On the hover state, and just for a moment, a black background fills the area that should be transparent, and then suddenly it gets transparent as it should. It looks as if the browser was too slow rendering the transparency.

    Any idea on how to fix that?

    Thanks.

    Copy & paste the code below to embed this comment.
  18. I’ve just done a writeup on how to turn this technique into a plugin.  I’ve also added a lot more animation flexibility.  The writeup is here:
    http://www.newmediacampaigns.com/page/css-sprites2-refactored-building-an-unobtrusive-jquery-plugin

    Copy & paste the code below to embed this comment.
  19. This is really an interesting technique. And probably there are also some other fields except from the navigation where you can use the sliding background. You only have to be creative!

    Copy & paste the code below to embed this comment.
  20. I think this article is quite lacking. We “all” know about CSS sprites by now and this cut and paste jQuery fluff just isn’t enough to be a whole article? I think you should have made this whole article a “Part I” and then expanded on the concept adding sub navigation, sub-sub.. navigation.

    You should and also have made some real-world examples where this actually would improve anything that we have not yet seen that much of – this “we” see every day and it just isn’t worthy of an ALA-article? …

    Good instructions for newbies though.

    Copy & paste the code below to embed this comment.
  21. Terribly sorry to be posting on the CSS Sprites2 thread, but the comments link on the original Sprites page seems to be broken. I’m working on a vertical menu application for the original Sprites, but I’m having some problems translating the code—specifically I’m having trouble assigning a larger height to a taller link. The link in question is the “Get Tapped In” link on the left side here: http://www.woodntap.com/new/

    This is the CSS: http://www.woodntap.com/new/css/wnt_home.css

    I’m sure I’m just overlooking something fairly obvious—any ideas?

    Copy & paste the code below to embed this comment.
  22. @Brian Lee

    The link elements are only as high as the text which they contain. You need to give the anchor a bit more height:

    #tapin a
    {
            height: 75px;
    }

    Copy & paste the code below to embed this comment.
  23. Well that didn’t exactly render how it showed in the preview.

    How is one suppose to quote code with this Textile thing anyway? (Markdown support and an accurate preview would be nice).

    Copy & paste the code below to embed this comment.
  24. Of course—just as obvious as I expected! Thanks for the help, Jason.

    Copy & paste the code below to embed this comment.
  25. I rewrote CSS Sprites2 in Prototype and script.aculo.us. My version of CSS Sprites2 is almost exactly the same as the Dave’s: it requires the same HTML, the same styling and includes a similar pre-built function used to invoke it. However, the Prototype version also includes keyboard support: there’s a matching focus, blur, keydown and keyup event handler for each mouse event handler.

    You can get it here: http://jeffreybarke.net/2008/11/css-sprites2/

    Copy & paste the code below to embed this comment.
  26. I noticed that if you mousedown and then dragout out of the button area. it stays in the hover state.

    Copy & paste the code below to embed this comment.
  27. This script does not work for the effects advertised in this site. It will work for just a basic background swithout.
    If you are just looking for a basic rollover, it will work.
    However, there are much simpler scripts out there for his .
    The sprites2.js DOES NOT WORK.
    Tested in FF3, IE6 and 7 (who cares about Safari)

    Glad i could save someone a few minutes!! :(

    Copy & paste the code below to embed this comment.
  28. External scripts are usually used by advertisers. Personally, I have them disabled. and so do other people. For example the confused people in previous comments that claim the example script doesn’t work. caching isn’t everything, and it’s not worth the security risk you put your users in. Google APIs or not, you can’t trust them. or at least your users wont.

    Copy & paste the code below to embed this comment.
  29. The examples embedded in the article itself don’t seem to be working for me in IE6.  I’m on a mac and using VMware Fusion to test in IE6—perhaps that’s the problem?  Works in FF and IE7 in Fusion, but in IE6/Fusion I have to hover over a button for about 7 seconds and then it finally just switches to the rollover state.  I don’t have a resource, at the moment, to test in IE6 without Fusion.  Any clues anyone?

    Copy & paste the code below to embed this comment.
  30. I have been a hold out – using unobtrusive javascript rollovers instead of sprites. I finally tried it out and must say that sprites were easy to implement, made the development process faster since I had fewer images to slice and I really liked using the fade in for the menu tabs on my website.

    Copy & paste the code below to embed this comment.
  31. One glitch I’ve seen that is driving me crazy, and it only happens for my Mac in my Firefox, not in my Safari and not for my PC friend in Internet Explorer…

    When I hover over a button, then hold the cursor there for a second or two, and move it WITHIN the <a> the sprite refreshes.  I don’t even move it outside of the button, any movement within the button after a delay refreshes the image and causes a new fade in.  Its similar to a flicker or a flash, and completely ruins the continuity of the menu.

    Any ideas what this is and how to solve this?

    Copy & paste the code below to embed this comment.
  32. I found a machine with IE6, to test on, and it works!  so, i guess it’s just an issue with testing in IE6 on my mac, using a virtual machine / VMware Fusion.  Thanks!

    Copy & paste the code below to embed this comment.
  33. Great article, I may say. I’ve tried to attach this effect on my Wordpress blog these two days but with no success. No matter how much I trie I can’t get it to work with the built-in list command (wp_list_pages) in Wordpress. Does anyone have any suggestions on how to make this work with Wordpress?

    TIA
    Daniel

    Copy & paste the code below to embed this comment.
  34. Finally after a few months waiting on my queue, I completed the mootools port:

    http://blog.gonchuki.com/archives/css-sprites2-its-mootools-time/

    same compatibility level as the version in this article, so if you are into mootools you can get the same experience in “the other side of the fence”.

    Copy & paste the code below to embed this comment.
  35. Hi. I don’t like absolutely positioned navigation elements. They’re useless for practical purposes.

    I am trying to get this example working with the following HTML:

    <ul id=“nav”>
      <li>Articles</li>
      <li>News</li>
      <li>Contact</li>

    </ul>


    My CSS is like this:

    /* Nav */
    ul#nav { padding: 0; display: block; float: right; margin: 5% 20% 0 0}
    ul#nav li { background: transparent; margin:0; padding:0; height: 20px; list-style:none; width: 130px; display: block; border: 0 }
    ul#nav li a { background: url(/av/nav.png) no-repeat; width: 130px; display: block; height: 16px; text-align: left; text-indent: -10000%; margin:0; overflow: hidden }

    a#arti { background-position: 0 0; }
    a#arti:hover, a#arti:active { background-position: -129px 0px;}
    li.curr a#arti, li.curr a#arti:hover { background-position: -258px 0px; }


    ..and so on. Basically the code is NOT working. What do I need to do to make sure non-absolute items work too?

    Copy & paste the code below to embed this comment.
  36. Whats with the textile drivel here? A website about web design cannot use a more modern system for commenting that allows us to post some simple code?

    Copy & paste the code below to embed this comment.
  37. For so much effort as to include a JS file and whatnot, this simply does not work.

    (1) In Firefox in Mac (which is quite a prevalent environment now) it flickers forever.

    (2) Doesn’t work consistently in IE7. Sometimes the animation doesn’t happen at all, and other times happens jerkily.

    (3) This whole shebang doesn’t work with a vertical sprite at all. Silly shite.

    Sorry. I appreciate the effort on the part of the writer, but even with loads of tweaking, this drivel simply does not work with vertical sprites because of the DIV that is appended to the css links. That may work for horizontal sprites, but in a vertical menu it is all over the place.

    Copy & paste the code below to embed this comment.
  38. This menu is beautiful and is a wonderful tutorial for those new to jquery and manipulating css. Thanks very much for the post, I have benefitted from this tremendously!

    Copy & paste the code below to embed this comment.
  39. I love the way you have this packaged up. How difficult would it be to introduce parameters for the image positions as opposed to hard coding?

    Copy & paste the code below to embed this comment.
  40. Try as I might, I can’t get this to work. I’m seeing nothing on rollover (in FF3 Mac) and then, on rollout, it switches to the rollover state for a few milliseconds and then fades out. In Safari, when I rollover, it flickers and tries to run the fade in/fade out over each pixel I move the mouse. When I look in Firebug in FF3, rollout causes a slew of classes to be created and then they slowly remove themselves. In Safari, moving the mouse in rollover causes the same thing. Active state works fine, though.

    I thought it might be an issue with the newer version of jQuery, but I switched out 1.3.2 for 1.2.6 and still had the same issues.

    I have pretty much no experience with JS, so I’m at a loss to troubleshoot it. Any ideas?

    Copy & paste the code below to embed this comment.
  41. I’m also having issues with my buttons flickering in FF3 for the Mac and one of my associates sees it in FF3 for Windows.  However, when I check the page showing the final example in your article in the same browsers the rollovers work beautifully.  I’m using a similar structure in my menu and the same js file, so the only thing I can think that would be different is the CSS.  I’d love to figure out a fix for this because it’s a great effect.

    Copy & paste the code below to embed this comment.
  42. Thank you for the great article.

    By removing onmousedown- and onmouseup-events though I’ll reduce the size of the js and css in half, and still have awesome results.

    Copy & paste the code below to embed this comment.
  43. Hi There,
    Thanks for a great insight into jquery sprites!!
    I have tried to apply this tut to a menu I am working on and it seems to work fine apart from the selected state.

    I can only get a selected state to work for the second li item??

    I change the <ul class=“nav current- “> to my required state and nothing happens.

    My menu list is – Home, Team, Contact Us and Links. I have changed the references in the css and script.js (from example 5) to match and still n luck?

    Do you have any suggestions??

    Cheers
    Archie

    Copy & paste the code below to embed this comment.
  44. I’ve been playing with this using transparent PNGs for the menu, and it is not working correctly….I think.

    When the page loads, I see is the menu starting position rendered correctly. However, the rollover events are not correct, because both the normal state and the hover state are being shown.

    I believe this is because the menu image is applied in two places, but only one is being turned off on events. The menu image is applied to “.nav” and to “.nav .home a:hover” but the “.nav” class background is not adjusted. So it continues to show through the :hover state due to the transparent nature of the PNG.

    Is there a solution for this? Help is very much appreciated.

    Copy & paste the code below to embed this comment.
  45. I just want to one pixel image repeat.however,the result is’t enough to answer my question,all about css sprites links,I need you help? thank you!

    Copy & paste the code below to embed this comment.
  46. Hy there.

    I tooked the time to read all the comments and saw that nobody asked about my problem.

    I managed to addapt the menu to my website and get rid of absolute position. But i’m having trouble, since my menu is generated, every li has multiple clases. How can i make the js code to work ..is there a posibility to ajust in such a matter that will get only the first class of the li?

    Thank you for your help.

    Copy & paste the code below to embed this comment.