"Having an active menu item usually means using some JavaScript to accomplish it. There’s nothing wrong with JavaScript, but if you can do with CSS, then that’s always the better route to take. If you run a WordPress site then you have an easy way to accomplish pure CSS active menu items using the nav-menu. I’m going to take you step by step in this tutorial creating a menu, adding classes to your page’s body tag and menu items, and setting up the CSS.
Step 1 Create a “Home” Link
First, open up your function.php and copy this code into it.function home_page_menu_item( $args ) { $args['show_home'] = true; return $args; } add_filter( 'wp_page_menu_args', 'home_page_menu_item' );This code will create a “Home” option in the “Pages” area in the Appearance->Menus section of your admin panel. When you put in your menu, it will create a “Home” link.
Why WordPress doesn’t have this by default is beyond me.
Step 2 Setup the Menu
Now, copy this bit of code (if you don’t already have it) to your functions.php file.if ( function_exists( 'register_nav_menus' ) ) { register_nav_menus( array( 'top-menu' => 'Top Menu' ) ); }This will create a new menu for the “Theme Locations” area. You may already have the “register_nav_menu” function in your fucntions.php file. If you do, you can add the “top-menu” or just use one of you existing menus.
Step 3 Create Dynamic Body Tag Classes
Next, you want to add this code to you functions.php file.function custom_body_class($classes) { $post_name_prefix = 'postname-'; $page_name_prefix = 'pagename-'; $single_term_prefix = 'single-'; $single_parent_prefix = 'parent-'; $category_parent_prefix = 'parent-cat-'; $term_parent_prefix = 'parent-term-'; $site_prefix = 'site-'; global $wp_query; if ( is_single() ) { $wp_query->post = $wp_query->posts[0]; setup_postdata($wp_query->post); $classes[] = $post_name_prefix . $wp_query->post->post_name; $taxonomies = array_filter( get_post_taxonomies($wp_query->post->ID), "is_taxonomy_hierarchical" ); foreach ( $taxonomies as $taxonomy ) { $tax_name = ( $taxonomy != 'category') ? $taxonomy . '-' : ''; $terms = get_the_terms($wp_query->post->ID, $taxonomy); if ( $terms ) { foreach( $terms as $term ) { if ( !empty($term->slug ) ) $classes[] = $single_term_prefix . $tax_name . sanitize_html_class($term->slug, $term->term_id); while ( $term->parent ) { $term = &get_term( (int) $term->parent, $taxonomy ); if ( !empty( $term->slug ) ) $classes[] = $single_parent_prefix . $tax_name . sanitize_html_class($term->slug, $term->term_id); } } } } } elseif ( is_archive() ) { if ( is_category() ) { $cat = $wp_query->get_queried_object(); while ( $cat->parent ) { $cat = &get_category( (int) $cat->parent); if ( !empty( $cat->slug ) ) $classes[] = $category_parent_prefix . sanitize_html_class($cat->slug, $cat->cat_ID); } } elseif ( is_tax() ) { $term = $wp_query->get_queried_object(); while ( $term->parent ) { $term = &get_term( (int) $term->parent, $term->taxonomy ); if ( !empty( $term->slug ) ) $classes[] = $term_parent_prefix . sanitize_html_class($term->slug, $term->term_id); } } } elseif ( is_page() ) { $wp_query->post = $wp_query->posts[0]; setup_postdata($wp_query->post); $classes[] = $page_name_prefix . $wp_query->post->post_name; } if ( is_multisite() ) { global $blog_id; $classes[] = $site_prefix . $blog_id; } return $classes; } add_filter('body_class', 'custom_body_class');This code is straight from the Ambrosite Body Class Enhanced Plugin. I opted to put this code in the functions.php file instead of the plugin to cut down on the amount of plugins I have.
What this code does, is it adds a class to the body tag based on the post-name, page-name, single-page, single-page-parent ,category-parent, term-parent and site name. We’re interested in the single-name and page-name parts.
OK, that’s all we need to do to the functions.php file.
Step 4 Create Custom WordPress Pages
Now, create a custom page for each of your menu item (this is optional, but I recommend it so you can have unique page setups). For the sake of this tutorial I’m going to create a three item menu. It will include “Home”, “Blog”, and “About”.Here’s how you create custom WordPress pages.
Create a new php file. In that file place this code
/* Template Name: yourCustomPage */Save the file as the same name as the Template Name. Now your custom page should show up in the Page Attributes section for new pages.
That’s it, easy-peasy.
If your custom pages doesn’t show in your Page Attributes section. Go to Appearance and deactivate your theme then reactivate it.
Step 5 Create WordPress Pages and Categories
Next, go to your admin page and create some new pages for your menu items. This way you’ll have a landing page for each menu item. You don’t need to make a “Home” page because your site already has one (http://www.yousite.com). For the sake of this tutorial I’m going to make a three item menu. Home, About, and Blog.You also want to create categories for you posts. I created a “Blog” category for the “Blog” menu item. “Home” and “About” won’t need categories.
Alright, now you should have a custom page for each of you menu items and categories for your posts. Now, it’s time to make the menu.
Step 6 Creating the Menu
Go to Appearance->Menus in you admin panel. Name your menu and click “Create Menu”.After you create your menu. Go ahead and select the pages you want to have in you menu, and click “Add to Menu” then “Save Menu”.
Step 7 Add CSS Classes to the Menu Items
Open each menu item and in the “CSS Classes” field add a class. I put in home_item, about_item, and blog_item, but they can be anything you want. Just make sure each menu item has a unique name.If you don’t have a “CSS Classes” option go to the “Screen Options” tab at the top of the page and select “CSS Classes”.
Step 8 Adding the Menu to Your Site
Now, add your new menu to the “Top Menu” in your “Theme Locations” area.Go ahead and put your menu anywhere you want on your site with this bit of code.
<?php wp_nav_menu(array( 'theme_location' => 'top-menu') ); ?>The ‘top-menu’ comes from the register_nav_menus function we added earlier
Now, your menu should look like this.
Not very pretty, huh? OK, here’s some basic CSS for the menu.
.menu-main-menu-container ul li { list-style:none; float:left; background:#0F0; padding:5px; } .menu-main-menu-container ul li:hover { background:#F00; }That’s Much better.
Step 9 Styling the Active Menu Items
Now for the fun part. Remember the body tag class function we put in the functions.php file earlier? Well if you view source on your home page you should see something like this.<body class="home blog logged-in"> <div class="menu-main-menu-container"> <ul id="menu-main-menu"> <li id="menu-item-18" class="home_item menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-18"> <a href="http://my.projects.com/wordpress/">Home</a> </li> <li id="menu-item-19" class="about_item menu-item menu-item-type-post_type menu-item-object-page menu-item-19"> <a href="http://my.projects.com/wordpress/about/">About</a> </li> <li id="menu-item-20" class="blog_item menu-item menu-item-type-post_type menu-item-object-page menu-item-20"> <a href="http://my.projects.com/wordpress/blog/">Blog</a> </li> </ul> </div>You see, in the body tag there’s a “home” class, and in each of the menu items there’s the “CSS Classes” we added. The “home” class is generated by WordPress, not the custom body class code we put in the functions.php file
The about page body tag looks like this.
<body class="page page-id-10 page-template page-template-about-php logged-in pagename-about">A blog post will look like this.
<body class="single single-post postid-1 single-format-standard logged-in postname-hello-world single-blog">Finally, add the CSS for the active menu items.
.home .menu-main-menu-container .home_item, .pagename-blog .menu-main-menu-container .blog_item, .single-blog .menu-main-menu-container .blog_item, .pagename-about .menu-main-menu-container .about_item { background:#999; }This CSS will check the page’s body tag (e.g The home page “home” class, the about page “pagename-about” class, or the blog page “single-blog” class). Then apply the styling to the corresponding menu item.
Just remember to select the appropriate category for you posts.
There you go pure CSS active menu items for your WordPress nav-menu."