Adding Icons to WordPress Menus

It’s easier than you might think.

Adding icons to WordPress custom menus is really a relatively simple 2-step process that does not involve any php coding whatsoever.

None. Zip. Nada. Zilch. All we want to accomplish is upload the icons we wish to utilize to our WordPress media library, after which futz with all the CSS to get stuff looking awesome.

Step #1, uploading images, is the really easy part. Step #2, futzing with the CSS, can get a bit complicated. For example, if your theme uses gradient colors on menu items when you hover your mouse pointer over them, you must hunt down those style rules within your style-sheet.

But, no worries, that’s what this tutorial is all about: to make it as simple as you possibly can for you to definitely just add the icons you need to the menu items you want. Why not only make use of a plugin? Simple really: one less plugin to update (if it gets updated); or break when WordPress updates; less server load too. Plus, plugins with icon functionality actually replace your existing menu with a new style. This method simply works along with your current design.

Before we begin, here’s a fast word about editing your style-sheet (I always add this to all my CSS tuts). There are 3 ways you can add custom CSS to your theme or child-theme (and use of a child-theme is strongly suggested if you’re gonna be customizing anything!)

  • Add custom styles directly towards the child-theme’s style.css file and upload via FTP.
  • Add them via the “Theme Editor” in your WordPress admin area.
  • Use the newest “Custom CSS” panel added to Jetpack (gotta love it!)

If you’re handy with CSS and wish to jump right in, scroll down towards the end of this tutorial where you’ll begin to see the full CSS required for 4 menu items with icons, including padding and CSS3 gradients on hover. Just copy/paste and play around. Ready? Let’s get started.

Upload some cool menu icons

Like I said, this really is the easy part. Simply select the icons you need to utilize for the menu items, and upload these to your WordPress media library. Don’t have worthwhile icons handy? One of the greater popular sets is FamFamFam. Or visit Free Icons Web for over 30,000 of them!

Be sure that the icons you upload fit the existing size of your menu items. For example, the navigation bar in Twenty-Eleven (WordPress default theme) includes a height of 43pixels. So, anything from 16x16px to 24x24px is ideal. Once you’ve uploaded all of your images, copy their File URLs to a blank text file and maintain it handy.

Identify the key nav container

In order to get individual icons to appear on individual menu items, we first must identify the key navigation container. To do that, launch your browser’s developer tools. If you’re uncertain how to do that, see “Tip #1″ within this post for help.

Got your developer tools open? Good. The ID or class of the primary navigation container will differ from theme to theme. While it can be considered a div, a ul or in more recent themes a nav, and it can be called just about anything, it’s usually quite evident. In our theme, the primary nav ID is nav#access as seen in the screenshot from Firebug below. To keep it handy, copy that ID – or class – to a text file (you can use the main one you opened earlier to your image URLs).

Target individual menu items

Here’s where things possess the potential to get a bit complicated. Why? Because we possess a choice to make before we continue: you can find 3 methods to target the individual menu items within our CSS, and each has its advantages and drawbacks. Let’s have a quick look at each and every method, get the best one for our needs, then jump right in.

  1. li:nth-child(n). This method doesn’t genuinely have any advantages for our purpose. It doesn’t operate in older browsers. If you alter your order of your menu items, or add a fresh item in between existing ones, you’ll must edit your CSS to switch your icons around. So let’s not really bother with this one.
  2. li:first-child + li. Although this method does work in all browsers, it has exactly the same major drawback as #1: in the wedding you improve your menu in any way, you still have to switch the icons around. No good.
  3. Use the numerical class assigned automatically by WordPress to every menu item. The dual good thing about this method is that it works without fail in every browsers, and is constantly on the work even if you change the order of your menu items, or add something new. The drawback is… huh, no drawback. OK. Let’s use this method

So we need to get the class of every menu item we want to include an icon to. Why not the ID of those items? Simply because many themes don’t assign specific IDs to menu list items. WordPress however, automatically assigns classes to each and every item inside your custom menu. (Be sure you’re inspecting a menu you made yourself, and not the default menu that is sold with many themes. Many of those will use a “Home” link that’s hard-coded and not have any class or ID assigned to it. Not best for our purpose.)

Using your developer tools, highlight/inspect the first item within your menu. That’s likely the “Home” link (unless you’ve put something different there). The link itself (the <a> tag) likely has no identifier. That’s OK, ‘cuz that which you want will be the automatically-assigned numerical class of their email list item (the <li> tag) it resides in. There are likely a whole bunch of classes that happen to be automatically assigned to each item, all in neat rows. Look for your one which includes a number appended to it. The screenshot below shows in places you can discover that numerical class. In this example, the numerical class assigned for the first item within the menu I made is menu-item-30.

Note that the ID of their email list item is the same as the numerical class. That’s just how WordPress works. Plus, there’s another reason we would like the category and not the ID: whenever we get to modifying the design rules for our menu, using the ID will often cause the specificity to be too much and override existing rules that individuals want to keep. That means adding more custom rules to the style-sheet to override that which you previously overrode. Ever tried swimming in molasses?

If you’re unsure what CSS specificity is, see this article for a simple explanation, and this one for any complete writeup.

OK. We’ve got the ID of the primary nav container, as well as the class of the 1st menu item within the list. Now let’s have an icon in there, shall we? We want to incorporate the icon as a background image towards the link (the <a> tag) that sits inside the list item. So our CSS selector will be this:

access .menu-item-30 a

…and the complete CSS to obtain a custom icon to display for this particular menu list item will be this:

access .menu-item-30 a {
background:url('FULL-URL-TO-YOUR-UPLOADED-IMAGE-GOES-HERE') no-repeat 0.5em 0.5em #ffffff;
}

Copy the above code to your text file and, using the following breakdown, edit whatever needs editing for all of your menu items.

  • #access =The ID of the main nav container
  • .menu-item-30 = The class of their email list item within the main nav
  • a = The link inside the list item
  • url = The URL to your icon which you pasted earlier inside a text file
  • no-repeat = Ensures that your icon does not tile and fill the menu item
  • 0.5em 0.5em = If expressed in px, em, or %, it’s the distance of the icon in the left as well as the the surface of their email list item (in that order). It can be also expressed as follows: left top, left center, left bottom, center top, center center, center bottom, right top, right center, right bottom. (If you only specify one value, the other is likely to be set automatically to center, or 50%.)
  • #ffffff = The background hue of this list item. This can be also set to transparent should you want the color of the key nav container to exhibit through.

Once you’ve all your menu items defined as above, copy the complete shebang to your theme/child-theme’s style-sheet. If you have, say, 4 main items within your menu, your CSS could look like this:

access .menu-item-30 a {
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-31 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-32 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-33 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em #transparent;
}

Save and/or upload your style-sheet. Then go refresh any page on your own site. You should see your shiny new icons in each menu item you defined. Got ‘em? Cool, that wasn’t so hard. Ah, but they’re all scrunched up contrary to the text in the links, aren’t they? So we have to adjust the padding of those links. Add the following to your style-sheet and refresh again (adjust this to fit the current padding values of your theme).

access .menu-item-30 a, #access .menu-item-31 a, #access .menu-item-36 a, #access .menu-item-37 a {
padding:0 1.2125em 0 2.8em;
}

Next step: hover over any menu item. See the icon disappear? Now we must define the CSS hover properties for all those menu items.

Get stuff looking good on hover

This part isn’t really difficult at all ‘cuz we’ve already done every one of the hard stuff. To get things looking good on hover, we simply have to add a hover rule for each menu item. We need to add a rule for each item ‘cuz we have to call the setting image (the icon) again. This is what that rule would seem like for your 1st item inside the sample menu:

access .menu-item-30 a:hover, #access .menu-item-30 a:focus {
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em #efefef;
}

The only items that have changed in the hover rule are adding ‘:hover‘ to the ‘a‘ within the selector (plus a selector for ‘a:focus‘ which can be pretty much exactly the same thing), and also the different background color of the hyperlink (change that to whatever color you would like to use). Go ahead and add a similar hover rule now for everyone of your menu items, and save/upload your style-sheet again. Refresh a page in your site and you also should begin to see the icons now appear even when you hover your mouse pointer over them.

Menus with CSS3 gradient colors

If the menu of your theme uses CSS3 gradient colors on hover, and you want to keep using those colors, you’ll need to complete a bit of digging in your style-sheet, and modify a few things in the hover CSS we just wrote. You’ll first must discover the specific style rules for that background hover property of your main navigation links. Then, as each menu item now has a unique background image (icon), you need to add them for the background declaration of each menu item.

For example, looking through the style-sheet, we can note that the gradient hover rules for the background of the primary menu backpacks are as follows:

background: #f9f9f9; /* Show a solid color for older browsers /
background: -moz-linear-gradient(#f9f9f9, #e5e5e5);
background: -o-linear-gradient(#f9f9f9, #e5e5e5);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background: -webkit-linear-gradient(#f9f9f9, #e5e5e5);

You can observe that there needs to be a distinct declaration for each browser type (CSS3 being relatively recent for the browser-scape, there is really as yet no uniformly accepted approach to declare gradient colors). Here’s the way to modify the setting hover declarations we merely wrote to range from the CSS3 gradients:

access .menu-item-30 a:hover, #access .menu-item-30 a:focus {
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em #efefef; /* Show a solid color for older browsers /
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -moz-linear-gradient(#f9f9f9, #e5e5e5);
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -o-linear-gradient(#f9f9f9, #e5e5e5);
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -webkit-linear-gradient(#f9f9f9, #e5e5e5);
}

As mentioned above, you’ll need to modify the hover properties of each menu item you added an icon to in order to have the gradient colors to display properly on hover.

Let’s end this having a full monty

Here’s the complete CSS for 4 menu items with icons, including required padding, and all the hover properties for CSS3 gradients in our theme. If you’ve a lot more than 4 items, just copy/paste and mess around with it.

access .menu-item-30 a, #access .menu-item-31 a, #access .menu-item-36 a, #access .menu-item-37 a {
padding:0 1.2125em 0 2.8em;
} access .menu-item-30 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-31 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-32 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-33 a { background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em #transparent;
} access .menu-item-30 a:hover, #access .menu-item-30 a:focus { background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em #efefef; /* Show a solid color for older browsers / background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -moz-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -o-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background:url('http://example.com/wp-content/uploads/2012/09/icon-30.png') no-repeat 0.5em 0.5em, -webkit-linear-gradient(#f9f9f9, #e5e5e5);
} access .menu-item-31 a:hover, #access .menu-item-31 a:focus { background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em #efefef; /* Show a solid color for older browsers / background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em, -moz-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em, -o-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em, -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background:url('http://example.com/wp-content/uploads/2012/09/icon-31.png') no-repeat 0.5em 0.5em, -webkit-linear-gradient(#f9f9f9, #e5e5e5);
} access .menu-item-32 a:hover, #access .menu-item-32 a:focus { background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em #efefef; /* Show a solid color for older browsers / background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em, -moz-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em, -o-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em, -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background:url('http://example.com/wp-content/uploads/2012/09/icon-32.png') no-repeat 0.5em 0.5em, -webkit-linear-gradient(#f9f9f9, #e5e5e5);
} access .menu-item-33 a:hover, #access .menu-item-33 a:focus { background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em #efefef; /* Show a solid color for older browsers / background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em, -moz-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em, -o-linear-gradient(#f9f9f9, #e5e5e5); background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em, -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); / Older webkit syntax */
background:url('http://example.com/wp-content/uploads/2012/09/icon-33.png') no-repeat 0.5em 0.5em, -webkit-linear-gradient(#f9f9f9, #e5e5e5);
}
Facebook
Google+
Twitter
LinkedIn
Pinterest

No comment yet, add your voice below!


Add a Comment

Your email address will not be published. Required fields are marked *

Comment *
Name *
Email *
Website