Make a WordPress Menu that Stands Out From the Crowd

WordPress Menu Images - A tutorial to add custom images to your WordPress menu

Create a truly unique WordPress menu

This little tutorial will show you how easy it is to create an image-based custom menu for your WordPress site or blog, similar to the screenshot below (taken from the Twenty-Eleven theme with header image hidden for clarity). It only works for a menu with top-level items only though; sorry, no sub-menus. I haven’t yet figured out a way to do this with drop-down sub-menus; when I do though, I’ll definitely do another write-up!

WordPress Menu Images - Screenshot of Twenty-Eleven theme with image menu

Don’t worry, we won’t be doing anything complicated with php, or javascript, or jquery. Everything in this article can be done by simply uploading images to your WordPress media library, and adding a few new style rules to your active theme’s style-sheet.

Find the main nav ID

Regardless of the theme you’re using, you first need to find the ID of the main navigation container. If you don’t know what that ID is, you can easily find it using your browser’s developer tools (see the “Identify the main nav container” section of this post for some tips). Got the ID? Good.

Upload your images

Simply upload your menu item images to your WordPress media library, and copy the file URLs to a blank text file to keep them handy (we’re gonna need them for the CSS). If you’d like to use the same images I’ve used for the example in this article, you can download the zip here.

Create a WordPress menu

It may be a good idea to create a test menu for this exercise. In the example screenshot above, the 5 item names are rather evident, but you can name yours anything you like.

Assign your menu item classes

To be able to assign a specific image to each menu item, we need to assign a specific CSS class to each one of them. If you don’t already see the “CSS classes” option for individual menu items in your WordPress menu editor, click the “Screen Options” tab at the top-right of your screen, then tick the “CSS Classes” checkbox (see screenshot below).

WordPress Menu Images - How to assign CSS classes to WordPress menu items

Give each menu item in your test menu a unique class name, for example: menu-bg1, menu-bg2, menu-bg3, etc. Save your menu, then select it in the “Theme locations” box at the top-left of your menu editor screen. Now refresh any page on your site to make sure your menu shows up. See your new menu? Good, let’s get the images in there.

The CSS you’ll need

Below is the basic CSS you’ll need to add to your WordPress theme’s style-sheet (I do hope you’re using a child-theme!). If you’ve used the images from the example zip file, or made your own the same size (122x40px), you don’t need to adjust the padding or width in the 1st style rule (if your own images are a different size, adjust accordingly). You do need to edit each occurrence of 2 things specific to your theme though:

  • #access = the ID of your theme’s main nav container
  • .menu-bg* = the CSS classes you assigned to your menu items

If you want a purely image-based WordPress menu, simply set the color in the first style rule to transparent. This will effectively hide the link text from view.

#access .menu-bg1 a, #access .menu-bg1 a:hover, #access .menu-bg1 a:focus, 
#access .menu-bg2 a, #access .menu-bg2 a:hover, #access .menu-bg2 a:focus, 
#access .menu-bg3 a, #access .menu-bg3 a:hover, #access .menu-bg3 a:focus, 
#access .menu-bg4 a, #access .menu-bg4 a:hover, #access .menu-bg4 a:focus, 
#access .menu-bg5 a, #access .menu-bg5 a:hover, #access .menu-bg5 a:focus {
background-repeat:no-repeat;
background-position:0.5em 0.5em;
color:#555;
padding:10px 0 0 60px;
width:70px;
}
#access .menu-bg1 a, #access .menu-bg1 a:hover, #access .menu-bg1 a:focus {
background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#1-GOES-HERE');
}
#access .menu-bg2 a, #access .menu-bg2 a:hover, #access .menu-bg2 a:focus {
background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#2-GOES-HERE');
}
#access .menu-bg3 a, #access .menu-bg3 a:hover, #access .menu-bg3 a:focus {
background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#3-GOES-HERE');
}
#access .menu-bg4 a, #access .menu-bg4 a:hover, #access .menu-bg4 a:focus {
background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#4-GOES-HERE');
}
#access .menu-bg5 a, #access .menu-bg5 a:hover, #access .menu-bg5 a:focus {
background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#5-GOES-HERE');
}

Save/upload your style-sheet, the refresh any page on your site. You should see your new images for each item in your WordPress menu. Note that you may need to adjust the background-position, padding and/or width in the first style rule above to get things looking just right for your site.

A simple hover effect

Finally, let’s add a little hover effect to each item in your new WordPress menu. This effect will simply give a bit of transparency to each image when you hover your mouse pointer over it, allowing the background color of your main nav container to show through. Go ahead and adjust the opacity and transition time to suit your own tastes.

#access .menu-bg1 a:hover, #access .menu-bg1 a:focus, 
#access .menu-bg2 a:hover, #access .menu-bg2 a:focus, 
#access .menu-bg3 a:hover, #access .menu-bg3 a:focus, 
#access .menu-bg4 a:hover, #access .menu-bg4 a:focus, 
#access .menu-bg5 a:hover, #access .menu-bg5 a:focus {
color:#fff;
opacity:0.7;
filter:alpha(opacity=70);
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-webkit-transition: all 0.5s;
-o-transition: all 0.5s;
}

That’s it, we’re done!

I hope you enjoyed this little WordPress menu tut and find use for it. If you need a hand with anything, or want to show off what you make with, please leave a comment below with a link to your site. Thanks for reading!

Tags ,

Comments (25)

    • Hi Andy,

      Glad the post came along at a good time (serendipity is a wonderful thing).

      Nice tip about the child-theme plugin too, thanks. But, if all you want to do is tweak the styles a bit, another option is to use the new Custom CSS module in Jetpack. See this post for more, it’s ossum :)

  1. hi. thanks for your nice tutorial, but i have a problem with adding submenus.
    when i add childs to the main-menus, they are not displayed correctly. i want the submenu-name be displayed, but instead i get a list of the menu-image for each submenu-entry (repeating) i gave the childs a different css-class but it wont work. any ideas please?

  2. Being a newbe on wordpress this article was of great help. I have created a menu with images so that I have been able to use a certain unusual font, and that looked great. Also I created a second image for all items with the text in a different colour for hover, focus and that worked also very well.

    I’m stuck at the last step of my plan, to have the second image for any of the items to stay indicating the active page in the menu. (I understand it that the last post only uses one image that is used as active in any of the items and that won’t work for me.)

    Thanks!

  3. Maybe this topic is not active anymore but – the menu item images are not displayed correctly on (at least) iPhone5. They are chopped off only showing the top half of image. Any solution to this?

    • Hi jannes,

      For your first question, all you need to do is target the specific ccs classes just like in the previous steps. So, to have different images for the active links, simply use something like this, and add a new one for each menu item class:

      #access .menu-bg1 a:active {
      background-image:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-#1-GOES-HERE');
      }

      For your 2nd question, you’re gonna need to bone up on media queries to help you increase the padding and/or margin on smaller viewports. Here’s an article in series I began awhile back (since abandoned) to help get you started: http://wpmu.org/how-to-customize-responsive-wordpress-themes-part-4-media-queries/

  4. Thanks a lot for this !
    I just have one question : the menu appears like a list

    - Item 1
    - Item 2
    - Item 3

    How could I make it appear like this instead :

    Item 1 I Item 2 I Item 3

    Thanks !

  5. Hey Patrick,

    I’m having a little trouble getting this to work…

    The images are getting bumped below the written version of the button, I’m not sure how to deal with that… Any ideas?

    http://www.royafraser.co.uk

    Would really appreciate some guidance, your tutorial is otherwise super easy to follow, I’m just not savvy enough to hop over this trip wire…

    Cheers!

    • Hey there @dickon_stone

      It looks like your images are getting bumped due to the padding in your links (line 129 of your style-sheet). It’s currently set to: 10px 0 0 60px which doesn’t create enough room to accommodate the size of those background images.

      To correct the issue, change the padding to something like padding:20px 26px; which, along with the width that is defined (70px) will make the links the exact same width as your images (122px).

      Also, as your background image is hand-written text, you may want to make the actual link text transparent by changing that to color:transparent;

      Finally, you may want to check the first link in your menu (Blog) as it’s showing up twice. :)

      • Sorry should have replied here…

        Thanks Patrick, have been fiddling with the padding and having some luck.

        Still unsure why the first item of the menu (always the first item, not fixed to Blog) is repeating, I pasted in your code from above and edited accordingly, everything looks fine in my menus… No idea really.

        • Hi again!

          That is weird. It looks like the theme has some javascript that injects a “Home” link in there no matter what you set up for your custom menu.

          Your best bet would be to contact the theme author to see how you can prevent that.

          Or, you could get creative with a bit of super-specific CSS to try and hide the darned thing. Try the following; it should work to hide ONLY the first “a” element in the first “li” item in your main nav container.

          #menu_container ul li:first-child a:nth-of-type(1) {display:none;}

  6. Thanks Patrick, have been fiddling with the padding and having some luck.

    Still unsure why the first item of the menu (always the first item, not fixed to Blog) is repeating, I pasted in your code from above and edited accordingly, everything looks fine in my menus… No idea really.

Participate