An Image Wordpress Navigation with Hover and Active Links

Wordpress has some great functions to display a menu to the user (list_cats(), wp_list_pages(), etc.) but no straightforward way to incorporate images into these menus.

In this tutorial I’ll show you how to use your own image menu, apply a highlighting effect, and top it off with an active state as well.

1. Cut Up Menu

Go ahead and open up Photoshop and make a great looking menu. Then we’re going to slice n’ dice. I’ll walk you through this real quick. Click on the images below if you want a bigger picture of what I’m doing in Photoshop.

Wordpress Menu

Cut each individual image link from your menu. Second, press CRTL + N and a new window dialog will open up with the sizes of the cut you just made. Hit “OK”.

Wordpress Menu

Then paste our cut image to the new image window just created and save it within the “images” folder of your theme.

Wordpress Menu

2. Create Categories

If you’re starting from a fresh install of Wordpress, then you’ll need to go ahead and create the categories that you’ll be using as links for your navigation. Note: Make sure your “Category Slug” does not contain any spaces.

3. Modify header.php

For this example, the header.php will contain your menu. Let me give you the code and explain each part.

Place the follwing directly above your <body> tag:

<?php
if (is_home()) {
    $show_category = '';
    } else {
        $category = get_the_category(); 
        $show_category = ' id="'.$category[0]->cat_name.'"';
    }
?>

The first thing we hit is the IF statement. This asks if the page we’re currently viewing is the home page; if TRUE, then go ahead and assign an empty string value to $show_category. If the answer is FALSE, then we retrieve the current category we’re viewing by using get_the_category(). This retrieves an array of categories, since you can put an article in more than one category. However, we only want to retrieve the first category in this array, so we retrieve the first category ($category[0]) and grab its name (cat_name). We get the $show_category string ready with the required CSS properties and we’re ready to go. (If the cat_name is ‘XHTML’, then $show_category is id=”XHTML”.

<body<?php echo $show_category; ?>>

Next we have our modify our current body tag to echo the value given to use from the operation above. If we’re currently on the home page, then $show_category = ”, thus the output will be simply <body>. However, if we are viewing a category post, then it will look like <body id=”category_name_here”>.

We modified the $show_category string to include the CSS properties as opposed to included them later to maintain XHTML compliance. If we did not include the CSS properties and instead made ourtag look like <body id=”<?php echo$show_category; ?>>, then the homepage tag would look be <body id=”">.

Repalce current menu list with the following:

<div id="menu">
    <ul>
	<li><a class="xhtml-css" href="/category/xhtml-css"><span>xhtml-css</span></a></li>
 
	<li><a class="php-mysql" href="/category/php-mysql"><span>php-mysql</span></a></li>
 
	<li><a class="ajax" href="/category/ajax"><span>ajax</span></a></li>
 
	<li><a class="wordpress" href="/category/wordpress"><span>wordpress</span></a></li>
 
	<li><a class="joomla" href="/category/joomla"><span>joomla</span></a></li>
 
	<li><a class="other" href="/category/other/"><span>other</span></a></li>
    </ul>
</div>

Here I have a simple unordered list (<ul>) with each list-item (<li>) linking to its corresponding category archive. Each list-item containing its own unique class property. The category “xhtml-css” will be defined as li .xhtml-css in our CSS template. I added an addition <span> tag within each list-item for added SEO. We’re going to hide the text within the <span> tag later and instead show our image based navigation.

4. Modify CSS

Now for the fun part: giving our menu some shape.

#menu {
    display: block;
    width: 672px;
    float: left;
    background: #fff;
}

This just defines the container (<div id=”menu”>) that’s holding our menu.

#menu ul {
    margin: 1px;
    height: 20px;
    padding: 0;
}

This gives our unordered list some shape.

#menu li {
    list-style: none;
    display: inline;
}

We have to add the list-style:none to make those bullets go away, and finally we want each list-item to display in a line. So, naturally, we say display:inline.

#menu li a {
    margin: 2px 4px;
    padding: 0;
    display: block;
    float: left;
}

Again, simply making each link in our menu a block, and having it float left. The margin simply gives it spacing from the other blocks.

#menu a span {
    position: relative;
    display: block;
    z-index: -1;
}

Remember that <span> tag we added to each <li> above? By making the “z-index: -1″ here we make the text appear behind the content of the website, but still readable to screen readers and crawlers. This makes it so that search engines like Google can read your links while the average user only sees the image for that link. Some developers suggest using “display:none”, but Microsoft’s web crawler has a problem with this method.

li .xhtml-css {
    background: url(images/xhtml-css.gif) 0 0 no-repeat;
    display: block;
    width: 109px;
    height: 20px;
    outline: none;
}


Note: The image above should help you understand
how the “background-position” property works.

Here is where we display our image for the “xhtml-css” category. We named the image for this link “xhtml-css.gif” and stored it inside the theme’s image folder. We set trailing “0 0″ after background: url(images/xhtml-css.gif) to give the image the position 0 pixels from the left and 0 pixels from the top (basically, it stays where it is). We also define “outline: none;” so that pesky dotted outline won’t appear around each image when you click it.

li .xhtml-css:hover {
    background-position: 0 -20px;
}

This overrides the background: url(images/xhtml-css.gif) 0 0 no-repeat; and instead moves the image down 20 pixels to display the gray hover effect.

#xhtml-css li .xhtml-css {
    background-position: 0 -40px !important;
}

This looks very similar to the one above, but is slightly different. We added the ID (#) in before each class tag. The reason is that because the ID is being given to us from the <body id=”xhtml-css”> tag. For example, we are viewing the “xhtml-css” category. Using the operation is part 1, we made the <body> tag have the id “xhtml-css”, thus giving us <body id=” xhtml-css”>. In CSS form this looks like body #xhtml-css. We use our body ID (#xhtml-css), then add our list-item (#xhtml-css li), and lastly the class for that list-item (#xhtml-css li . xhtml-css).

Lastly, since we want to apply the same hover effect to each link (php-mysql, ajax, wordpress, Joomla and other categories) we simply add a coma and the next list-item.

li .xhtml-css:hover, li .php-mysql:hover, li .ajax:hover, li .joomla:hover , li .other:hover, li .wordpress:hover {
    background-position: 0 -20px;
}

We want to do the same for an active link.

#xhtml-css li .xhtml-css, #php-mysql li .php-mysql, #ajax li .ajax, #joomla li .joomla,
#other li .other, #wordpress li .wordpress {
    background-position: 0 -40px !important;
}

Other Modifications

If you have an article stored in mutliple categories, and you want each category link to be displayed as “active” when you are on that link, then we have to make a small modification to the code in section 2 (Modify your header.php):

<?php
foreach((get_the_category()) as $category) { 
    echo ' class="' . $category->cat_name . '"'; 
} 
?>

We replace the preview code with a “foreach” loop. What this does is it grabs all the categories that are currently active (any article that is being display that is filed under multiple categories), grabs the name of that category, and stores it to $show_category. For example, if we were viewing a category filed under “category1″ and “category2″, $show_category would be class="body-category1" class="body-category2". This makes it so the navigation would display the “active” image effect for those two category menu items.

Also note that I added “body-” within the class property. If we did not, then we would have two classes named “xhtml-css” when you viewed an article filed under “xhtml-css”. This is because we would have the body tag look something like <body class=”xhtml-css”> and the list-tem for that category be <li class=”xhtml-css”> which would shatter web standards. So, in order to complete this change, we’ll modify our “active” CSS properties to look something like this:

.body-xhtml-css li .xhtml-css, .body-php-mysql li .php-mysql, .body-ajax li .ajax, .body-joomla li .joomla , .body-other li .other, .body-wordpress li .wordpress {
    background-position: 0 -20px !important;
}

Conclusion

Adding an image-based navigation to Wordpress is not as hard as it seems. Using simple images is a great way to have your menu stand out from the rest of the site. Just don’t make it too flashy:-)

Hope your enjoyed this original tutorial! Feedback and questions are welcome in the comments below.

7 Responses to “An Image Wordpress Navigation with Hover and Active Links”

  1. Shane Says:

    Thank you for the tutorial! I just did something similiar on my site, but wish I had the active effects on it. I’m no CSS wiz either, so I’d bet the way I did it should have been done much differently. Is it possible to use your method to also do the active effect on pages that have menu links?

    Thank you!

  2. Patrick Sweeney Says:

    I’m assuming this would be possible to use pages instead of categories for this…..the only real difference would be to change the logic to see what page we were on and fetch the correct page right? Little confused…lol.
    Thanks!

  3. James Says:

    Hi, I found your blog on this new directory of WordPress Blogs at blackhatbootcamp.com/listofwordpressblogs. I dont know how your blog came up, must have been a typo, i duno. Anyways, I just clicked it and here I am. Your blog looks good. Have a nice day. James.

  4. Jason Says:

    Can you please tell me what exactly I would change to use PAGES instead of CATEGORIES. THANKS

  5. Florence Oliver Says:

    zcx5g6hq1192pmt1

  6. Blog Picture Says:

    Expert’s ideas. I appreciate this. Will try to apply the information provided herein and see the specific outcome in real situations. Many thanks.

  7. Patricia Says:

    Hi, this was really a great tutorial - thanks! I’m trying to get this working with a purely Page driven WP site (as such no categories), so I’m a bit confused about what to enter as a PHP statement above the tag and within the tag…any tips would be great - likewise if I stumble upon a solution I’ll post here as well. thanks

Leave a Reply