How to Create a CSS Menu Using Image Sprites

Read the full post

Add to Flipboard Magazine.

Follow these steps to build your own modern navigation bar design, starting with the initial steps in Photoshop to flesh out the design, then moving on to constructing the HTML and styling with the CSS image sprite technique. However, if all that sounds too strenuous, there’s also a handy download of the source files especially for you!

CSS menu design tutorial

View Demo


CSS menu

Start work in Adobe Photoshop and create a new document at your desired size. Grab the Rounded Rectangle shape tool and draw a long, thin bar onto the canvas on its own layer.

create CSS menu

Double click the layer to open the layer style options. Add a Gradient Overlay spanning from a dark to light tone.

how create CSS menu

Head down to the Stroke options and add a thin outline stroke with a mid gray color.

create a CSS menu

The bar so far has a soft beveled appearance and is ready for being filled with menu options.

CSS menu

Use the Text Tool to type out a range of menu options. Being the Menu of Awesomeness, I’m selecting a bunch of awesome things from everyday life… Ninjas, Zombies, Robots etc.

CSS menu from scratch

Double click the text layer, then add a darker Gradient Overlay.

CSS menu web

Also select a subtle Drop Shadow using the Normal blending mode, a light gray swatch and just 1px in the Distance box.

CSS menu design

These little tweaks to the text give a nice chiseled effect to the menu design, simulating the subtle casts of light and shadow.

code a CSS menu

On a new layer, use the Mask Tool to draw a 1px line. Fill the selection with a color pick from the lower portion of the menu, then nudge the selection to the side and fill with a lighter shade. Duplicate this chiseled line between all menu items.

design a CSS menu

Group all the layers of the menu together, then make a copy. Rename the duplicate to indicate that it contains the hover effects.

CSS menu step tutorial

Head into the layer styles of each layer in the Hover group and adjust the gradients to appear slightly darker.

CSS menu totorial

The darker version of the menu will display when an item is hovered by the user’s mouse.

Stack the groups vertically so that one menu is sat above the other, then crop down the canvas to the exact dimensions of the graphics.

Save the graphic for the web, using a PNG file type to keep the graphics crisp and file size low.

Open up a code editor and flesh out the basic HTML. Being a list of options the menu is suited to the Unordered List tag. Create a link within each list item corresponding to the original concept.

CSS menu coding

We’ll also need a way to target each link individually, so add a class to each anchor element.

CSS menu code snippets

Create a new CSS file and begin with a quick reset to remove the default styling. We can then start to target the anchors within the lists. All the anchors will need transforming into a block element, they are all 56px tall (half the image size), all require the background sprite image and a text-indent to shift out the original text. These styling rules can all be crammed into the generic styling of the basic anchor, we can then get specific by targeting each class with individual styles.

CSS menu image sprites

With the general anchor styling and the first menu item given its specific width and background position coordinates the menu starts to shape up.

CSS menu web development

Each of the remaining list items can be given its unique styling, taking the background position coordinates by measuring from the top left corner. This essentially displays the correct section of the large image while the rest is hidden from view.

CSS menu steps

With all the items styled up, the menu is looking as planned, recreating the original concept with HTML and CSS coding.

CSS menu design steps

The menu still needs styling to produce the hover effects, list out a set of new styles but this time, set the background-position to -56px so that the lower half of the image is shown.

CSS menu learn desigb

A quick test in the browser shows the effect come to life. When a specific menu item is hovered over, the background image is shifted to display the darker version of the menu.

CSS menu design yourself

A common visual problem with some browsers is that the accessibility features that allow keyboard navigation don’t quite look as intended when a button is clicked. As you can see, a horrible dotted line is left right across the page.

CSS menu how

This can be removed in the CSS, but don’t stop there! If this visual cue is removed it is a major accessibility flaw unless an alternative is supplied. We can reproduce our own visual cue using the :focus selector.

CSS menu create

Check out the working demo of the menu, or feel free to download the source code to pull it apart and see how it all works.

View Demo


  • 187
100 HD Blurred Backgrounds

Join the mailing list to have new content delivered straight to your email inbox. Every subscriber gets a free pack of 100 HD Blurred Backgrounds + bonus 10 realistic web shadows.

100 HD Blurred Backgrounds

Written by Iggy

Iggy is a designer who loves experimenting with new web design techniques collating creative website designs. You can follow Iggy on Twitter.


  1. Marco says:

    Just sharing my 2 cents here Chris.

    Seriously, don’t learn others to do this:
    [b]* { margin:0; padding:0; }[/b]
    Although it’s good for “simple” examples like this one, some default elements (form / legend etc.) do need their default margin & padding to give the desired effect.

    Also, the menu “corners” should be transparant, because in your example you still see the white background.

    Otherwise, a very useful tut showing almost the menu ;) !

    • Thanks Marco

      Good point on the * reset. I do usually write ‘quick and dirty reset’ in the comment which identifies a not-so-clever method, but obviously didn’t in this example.

      I knew someone would spot the corners! haha. It was originally built as a one off, then decided to create the whole demo as an after-thought :-)

    • Wayne says:

      I disagree about the * reset. forms / legends and many other elements may have defaults, but they are not consistent between browsers. A * reset was lesson one when I was taught cross-browser compatibile CSS. That means that… yes… you have to reapply all the margins and padding, but at least you know that it’s actually going where you want it.

      • asdasas says:

        Hi, disagree about the * reset. forms / legends and many other elements may have defaults, but they are not consistent between browsers. A * reset was lesson one when I was taught cross-browser compatibile CSS. That means that… yes… you have to reapply all the margins and padding, but at least yo

  2. sonichtml says:

    Nice~ thank you for shared.

  3. Dave says:

    Hi! Sry my english is not so good :(
    Whats about the probelm with
    hidden text and links with Google SEO! You use a text-indent -9999.
    Please look at:

    Isnt it a problem?

    • It’s a common debate but the use of hidden elements is fine when used in this sense where it isn’t adding any extra value to the page. It’s simply replacing the text word-for-word, whereas if the hidden text was stuffed full of keywords that that’s when there could be trouble.

      • Dave says:

        Hmm. But can google make a different between a word-for-word “list Element text-indent” and a ” or text-indent” with full of keywords? (Hope you understand what i mean). Google cant read the text from the “picture” and compare it with the “text”. I have read a lot about “small” homepages (not big like apple for example) …that they have trouble with google. So iam a bit afraid of this technique.

        • Dave says:

          sry…. a fault in my last message. I mean:

          …But can google make a different between a word-for-word “list Element text-indent” and a ”p or h2 text-indent” with full of keywords?

        • Mike says:

          Google can’t tell what the content of the picture is, but surely they can differentiate between a text-indent affecting one word and a text-indent used for stuffing several words.

    • Mikey says:

      Correct me if I’m wrong, but I thought text-indent -9999 only harmed SEO when you use in-line styles. Do Google’s bots really go and examine our external CSS files?

  4. Rahul Jadhav says:

    Nice tutorial. Just stumbled it

  5. really nice tutorial good way to use sprites.

  6. Sindustries says:

    The awesome thing is if you use a CSS sprite sheet the user only need to load one image!

    A good thing to do would be to included all your sites navigation backgrounds and icons on the one sheet and position them using css so instead of loading 10-20 images you can decrease this amount to … well one.

    If your really looking for a challenge you could keep the link text and use sliding doors while using CSS sprite’s ;) have fun.

    Great tut Chris.

  7. Davor says:

    Hi Chris!
    Tut is awesome and simple as always. Thinking of using sprites for my next project. The menu is awesome but the “download button” and the header text on this demo page is pure awesomeness! :D

  8. Jon says:

    Great tutorial for those who are just starting out using CSS. Everyone should be using this technique by now! Great tip for replacing the outline too, I really hate outlines!

  9. Nice tutorial Chris. Using sprites is THE best idea when you don’t want to use text hyperlinks in the menu. I also used sprites on my site to create the menu and jQuery to add a smooth animation effect. I think the best result pops up when you combine sprites with jQuery.

    P.S. Could you please let us/me know which jQuery tooltip plugin you’re using?

  10. Brendan says:

    It’s also handy to supply the ul#awesome-menu with the background to prevent flicker in older browsers; IE6 etc.

  11. I think this is completely wrong. It removes all possibilities of adding new menu elements. It’s great for a design company because the developers integrating the HTML will have to come back to them if they want a new menu item.

    • Mike says:

      Add more sprites to the right side of the original image and add another few lines of HTML and CSS. It’s not exactly rocketscience to identify and continue an established pattern.

  12. Bryan says:

    Still using Adobe photoshop for web work.. Leave it for the people who work with paper, Its so slow and cumbersome that even adobe does not recomend its use for web building….

  13. Will says:

    Seems to me the sprite should probably be a transparent png — if you’re using rounded corners as you are in this example. The demo has little white bits in the corners that makes an otherwise nice looking menu look a bit unfinished.

  14. Erik Ford says:

    Depending on the site I am developing, I either use this method or I use individual sprites for each list item. I find the longer the navigation system will be, the more I will use the latter as opposed to the former. Not certain if you allow links in your comments, but here is a down and dirty tut I wrote showing the latter:

  15. Jack F says:

    Would it be best instead of giving each link a class of say “ninja”, to give them an ID? as you probably wont give another element that same class? Other then that, nice tutorial.

  16. Mike Lewek says:

    Very Awesome Tutorial Chris.

  17. i am certainly gonna try this. that looks really “awsome” ;o)

    been around your website. first visit for me but probably not the last.
    thanks for sharing all this.

  18. this is awesome tutorial… nice one Chris.

  19. Ray M. says:

    Well done!

    This is a good case of where CSS3’s background-position-y would come in handy: For the hover states, we wouldn’t need to repeat the horizontal background positions.

  20. Jane says:

    excellent job! i don’t know if i do mine and if it would come out as good as sample!!

  21. michel says:


  22. Terese says:

    Great tutorial!! Learned a thing or two I didn’t know before.

  23. name says:

    menu flickers on rollover (firefox).

  24. Davor says:

    The corners are not transparent for simple reason that in IE6 this requires the PNG fix to be applied and this menu doesn’t work with PNG fix active in IE6.

    At least none of the fixes I tried to use. They all screw up background position.

    This could of been mentioned somewhere in the tut so that I don’t waste entire day building a web that doesn’t work in IE6.

    Nice tut anyway.

  25. Conrad says:

    What about the menu compatibility in IE 7?

  26. Ezrad Lionel says:

    I really love it when people completely miss the point and offer their 2 cents. Try to understand the scope of an article before offering suggestions, your mild retardation may be infectious.

  27. karfes' says:

    i like the tut coz it shows how to use photoshop very well. i completely needed the css n u got it all. thanx.

  28. Matt says:

    Great tute Chris, one I’ve been meaning to try but never got the headspace to do it. I’ve been a little adverse to using images in my menus but have decided that if it’s good enough for Apple it’s good enough for me.

  29. naveena says:

    If I like to add a drop down then, how I’m suppose to do in this following the same style.

    please help me

  30. Mark Weir says:

    Love the tutorial, but I’m having an issue with it in IE6 I can’t get the nav fixed at all.
    Can anyone help?
    Thank you so much

  31. Mark Weir says:

    Ah alas it was my own fault, somehow forgot to add
    ul#nav li {
    display: inline;

  32. espreson says:

    Regarding Hover effect:
    Hover color is looking odd…
    Underscore or underline or border-bottom will be better…

  33. hecbuma says:

    hi.. I few months I’ve learned this technique… rollover works fine, everything but still I had one little problem.. when a element its clicking a selection lines appears a cross the windows.. you can see it here on the center dropdown menu and on the right one..

    can u help me to avoid this?

  34. Andy says:

    Thanks a lot, these tutorials are really helpful!

  35. Lele says:

    Nice tut!

    I use a similar technique to do my navigation but was wondering how this style of nav could be applied to a drop down list ?

    Any help would be hugely appreciated!
    Thanks heaps

  36. theprodigyportal says:

    Nice tutorial.I have one question though..I am working for a project,I am trying to make an image a background so i can put another banner in top of it.Can you please help me?I have put my email address on the comments.If you dont mind please reply.Thanks.

  37. This is indeed a great article. CSS always plays a vital role in web design and it always gives you opportunity to make your website Google friendly. I have compiled few factors ‘why Google loves CSS’ that you can check at

  38. ivo says:

    Great tutorial, thanks!

  39. James says:

    Thank you for this tutorial, it was a big help.
    It was simple and easy to understand, and taught me how to make a very cool menu!

    much appreciated!

  40. Ben says:

    Very nice tutorial, clean and cutting edge.

    Thank you!

  41. sushil shirbhate says:

    Nice tutorial

  42. Mike Heath says:

    Great but would be much cooler still if the menu 1. had dropdown submenus
    and 2. achieved smooth rollover with jquery.
    Any chance of a supplementary tutorial showing how to do that?


  43. Giacomo says:

    Nice post, but….I notice a mistake in your article! IE6 don’t support “hover on Non-Anchor Elements”! Have a lokk here: . Just put the IDs in the “li” tag, and rewrite the css just a little, and it would work great. :-)

  44. Totoro says:

    Nice tutorial, but there are some bugs in it.
    The active state doesn’t work in IE7 and in Firefox when the active state is highlighted and you click anywhere on the screen the highlight disappears.

  45. Elijah says:

    Good Tips. Thank you so much

  46. darbez says:

    Thanks for sharing a such a wonderfull TUTS and hope I will visit u r tutorial again and agian


  47. paulo says:

    Thank you Chris, I’ve just followed each step and then implemented it into the footer of my website and…. it worked first time :) Can’t believe it, thank you for the excellent tutorial.

  48. Harsha M V says:

    great post. nice way of doing it.

  49. Energie says:

    Hello Chris,

    Thank you for great tutorial. If you don’t mind i need little help. I’ve tried something to fix it but i could’nt success. I would like to know how can i fix a problem with IE6. The problem is when you mouse over to menu its pushing other div to down. Thank you for helping.

  50. squareart says:

    Great tutorial, really love the possibilities this technique has. BUT I’m also having a problem in IE – shifting the menu down a bit.

    Chris if you could supply the “fix” for this that would be much appreciated. As such it leaves the menu unusable if you are considering IE users.

    Got to Love IE: )
    Thanks mate.

  51. Energie says:

    For my first post:

    IE6 fix: change display:block; to display:inline; from -li a- element.

    Working great this way. Thank you for tutorial again.

  52. Rohit says:

    thanks for sharing…..its jst awesome

  53. Shahriat Hossain says:

    Nice post and thanks for sharing your knowledge with us.

  54. jp says:

    AWESOME TUT! how would you make this menu verticle?

  55. Junaid says:

    Hi,,it’s very cool but it has some issue….when i click on any button it shows active button but when i click on anywhere on the screen the active effect gone…please help me!!!

Leave a response