Unitz LLC
Home   |   Unitz News   |   Contact Us

Using the WordPress 3.0 Menus Feature Part 2 – Styling and Animating

Bookmark and Share
Posted by Paul Reilly at 8:45 am on May 31, 2010 • General,Programming,User interfaces,WordPress

Welcome back! Since my first post, where I demonstrated the simple yet powerful WordPress 3.0 Menu Management functionality, WordPress 3.0 RC1 has been released! With this great new tool, WordPress has become an even more robust option for content management. Now non-technical users can easily manage the navigation (including drop-down menus) of their site through a WYSIWYG environment.

In this second post, I’m going to explore the code generated by this functionality, and give a simple demonstration of how to style and animate the generated menus using  CSS and jQuery. You can then use these skills to develop your own WordPress 3.0 theme and its menus.

Here’s a demonstration video of the end result. The menus were created using the WordPress Menu Management functionality and are set to animate down and fade in on mouseover, and utilize CSS3 gradients and rounded corners. Refer back to part I to see how the menus were created initially.

Our first step will be to add styling to the menus. As with the previous post, I am basing these instructions on the default WordPress 3.0 Theme “Twenty Ten.” It’s important to understand all of the pieces of code that come together to draw the menus. For this example, 3 files will come into play.

The first is header.php in the theme’s root directly. This is the file that draws the header part of your pages. In the Twenty Ten theme, it includes a call to wp_nav_menu(). This is the function that queries WordPress for the menu in HTML. It takes several optional parameters, which I won’t get into here – they’re described at http://codex.wordpress.org/Function_Reference/wp_nav_menu if you’d like to explore – they let you change CSS classes, wrapper <DIV>s, etc.

<div id="access">
<?php wp_nav_menu( array( 'sort_column' => 'menu_order', 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); ?>
</div>

Sample output of this function is below. You’ll notice that WordPress draws the menu out using unordered lists. They nest secondary menus in additional <ul> tags. This is a very popular method to organize navigation and is highly customizable with CSS. If you’re unfamiliar with this approach, A List Apart has a very good explanation.

<div id="access">
<div class="menu-header">
<ul id="menu-wordpress-sandbox-menu" class="menu">
	<li id="menu-item-17" class="menu-item"><a href="#">Fruits</a>
		<ul class="sub-menu">
			<li id="menu-item-19" class="menu-item"><a href="#">Oranges</a></li>
			<li id="menu-item-20" class="menu-item"><a href="#">Apples</a></li>
		</ul>
	</li>
	<li id="menu-item-32" class="menu-item"><a href="#">Colors</a>
		<ul class="sub-menu">
			<li id="menu-item-30" class="menu-item"><a href="#">Blue</a></li>
			<li id="menu-item-31" class="menu-item"><a href="#">Red</a></li>
		</ul>
	</li>
	<li id="menu-item-33" class="menu-item"><a href="#">Links</a>
		<ul class="sub-menu">
			<li id="menu-item-34" class="menu-item"><a href="#">Google</a></li>
			<li id="menu-item-35" class="menu-item"><a href="#">Yahoo!</a></li>
		</ul>
	</li>
</ul>
</div>
</div>

Comparing this HTML output to the accompanying sample images and video, you’ll notice the drop-down portion of the navigation is in the nested <UL>s with a CSS class of ‘sub-menu’. This is generated automatically by WordPress and this nesting structure is how you can add style and animation. Please note that for this demonstration, the HTML above has been simplified – my links are empty and I have also stripped out many additional class names that WordPress includes automatically for the UL’s and LI’s to make the HTML simpler to read. These classes can be very useful for detailed styling though, so consider reviewing your generated code when you do your implementation.

Now that we know how the menus are drawn in HTML, we can start to style and animate them. As mentioned earlier, my examples work on top of the Twenty Ten default WordPress 3.0 Theme, so I will show code from this theme. This theme has a GNU General Public License so we’re free to modify it and use it near any way we’d like – consider copying it and working on the copied version for your experimentation.

The CSS styles for the Twenty Ten theme are in the file styles.css in the main theme directory. Starting around line 370 of this file (in the RC1 version of WordPress at least), you’ll see a section of the CSS commented ‘Menu’ that starts defining the menu’s styles.

/* =Menu
-------------------------------------------------------------- */
#access {
	background: #000;
	margin: 0 auto;
	width: 940px;
	display:block;
	float:left;
}

Looking through this section of CSS, you’ll see the various styles that set the colors and fonts used in the menus. In my example, I changed the background colors for the nested sub-menu lists. I also added gradients to them (these gradients only work on CSS3 compatible browsers). Specifically I styled “#access ul ul a” like so (the background-image calls set the gradient):

#access ul ul a {
	background:#333;
	height:auto;
	line-height:1em;
	padding:10px;
	width: 160px;
	background-image: -moz-linear-gradient(100% 100% 90deg, #474747, #939393);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#939393), to(#474747));
}

I also added rounded corners to the bottom of each sub-menu. Again this isn’t support on all browsers. To do this I modified “#access ul ul,” adding the following CSS. The extra bottom padding gives room for the rounded corners.

#access ul ul {
	padding-bottom:10px;
	background-color:#474747;
	-moz-border-radius-bottomleft: 10px;
	-webkit-border-bottom-left-radius: 10px;
	-moz-border-radius-bottomright: 10px;
	-webkit-border-bottom-right-radius: 10px;
}

The key parts of the CSS that tell the menus to appear on mouseover are below:

#access ul ul {
	display:none;
	...
}

and

#access ul li:hover > ul {
	display:block;
}

The first part tells the browser not to initially display the nested menus, but the second says do show them when the parent item is moused-over. To get our animation working, we’re going to comment out the “display:block” CSS – we’re going to instead control the display menu event with JavaScript.

#access ul li:hover > ul {
	/*display:block;*/
}

The simplest way to do this is with the help of a JavaScript library like jQuery. WordPress already comes with jQuery so we need to load it in using the wp_enqueue_script function. The enqueue function is the safe way to add JavaScripts to WordPress to safeguard against various conflicts. We’re also going to load in a second JavaScript file we’re about to create called navigation.js.

Open up the header.php file and add

<?php 
 
wp_enqueue_script('jquery');
wp_enqueue_script('unitzNav', get_bloginfo('template_directory')."/navigation.js");
 
?>

to the HEAD section of the document. We’re now loading up the jQuery library automatically for use with every page. Now it’s time to create the navigation.js file we referenced earlier – create this file in the same directory as the rest of the theme files.

If you’re unfamiliar with the power of jQuery there are ample tutorials and discussions online. In a nutshell, jQuery makes once complicated JavaScript tasks very simple, that work in just about every browser. We’re going to be using a simple effect for our menu animation but, many jQuery menu plugins and navigation techniques are available that you can use as well. Here and here are resources to explore many such techniques.

Put the following in your navigation.js file:

jQuery(document).ready(function($) {
	//initial the menus
	$("ul.menu li").mouseover(function() {
		$(this).find("ul.sub-menu").animate({"height": "show", "opacity": "show"}, 800, "swing");
 
		$(this).hover(function() {}, function(){
			$(this).find("ul.sub-menu").animate({"height": "hide", "opacity": "hide"}, "slow");
		});
	});
});

Believe it or not, this short section of code is all it takes to get the drop down menu animation working across most browsers with jQuery. The outer wrapper is a jQuery function call that runs when the page is finished loading. It then tells the browser to animate open the instance of ul class=”sub-menu” whenever a parent list item is moused over. Then, using the hover function, it tells the browser to animate closed this same menu when either the parent item or menu is moused out.

On the jQuery website you can read more about this syntax and the available function parameters – many types of animations and effects can be used here.

This simple approach does have limitations – specifically, although the Twenty Ten theme and WordPress’s menu manager support more than two levels of navigation, this jQuery implementation does not and will break the lower menus. However, considering the relatively simple modifications, the effect is quite effective.

Thanks for taking the time to read these posts – I hope it gets you excited for the power of WordPress 3.0’s menu management and gets your thinking about ways to style and animate your own menus.

31 Comments

  1. [...] you’ll agree that it has significant potential (see the video at the end of the post). In my second post in this series, I’ll delve into the code and show how to make modifications to the display of [...]

    Pingback by Using the WordPress 3.0 Menus Feature Part 1 | U-notez at 8:43 am on June 1, 2010

  2. [...] This post was mentioned on Twitter by Stephanie and Paul Reilly, Unitz LLC. Unitz LLC said: The second post in my series on WordPress 3.0 Menus is up – http://is.gd/cy8IP – this time it's about styling and animating them with Jquery [...]

    Pingback by Tweets that mention Using the WordPress 3.0 Menus Feature Part 2 – Styling and Animating | U-notez -- Topsy.com at 9:37 am on June 1, 2010

  3. Do you know if the built-in menus function can be made into a vertical menu rather than the default horizontal implementation?

    Love your detailed CSS directions – thank you!

    Comment by Matt at 12:40 am on June 8, 2010

  4. Hey Matt – Sure you can! It’s all about how you style the css. This page http://ago.tanfa.co.uk/css/examples/menu/tutorial-v.html has a good tutorial on how to style vertical CSS menus. You need to merge the html that WordPress generates with the CSS styles demonstrated at that link. Good luck!

    Comment by Paul Reilly at 8:54 am on June 8, 2010

  5. Is it possible to create a custom URL that goes off site – but opens in a new window or tab? Right now external links in my drop-down menu just load in the same page. Thanks!

    Comment by Seth at 2:40 pm on June 15, 2010

  6. Hi Seth – That’s something I came across as well and I don’t know of a way to fix it directly through WordPress. I would have thought they would allow you to pick it the link should load in an external window or not, similar to adding links in the editor.

    There is a workaround solution though – you can use jQuery to append the target = _blank parameter to all links that aren’t local to your site. Here’s a snippet that should do the trick:

    jQuery(“a[href^='http:']“).not(“[href*='mydomain.com']“).attr(‘target’,’_blank’);

    This is from http://trevordavis.net/blog/tutorial/use-jquery-to-open-all-external-links-in-a-new-window/

    Good luck!

    Comment by Paul Reilly at 4:02 pm on June 15, 2010

  7. If you’ve been playing with the menus in the RC versions of WordPress 3.0 and upgraded to the final version yesterday – you may have noticed that the menus option has disappeared from your theme like I just did.

    It looks like they changed the call to enable the menus in the functions.php file from:

    add_theme_support(‘nav-menus’);

    to just

    add_theme_support(‘menus’);

    This fixed it for me.

    Comment by Paul Reilly at 1:25 pm on June 18, 2010

  8. I’m confused by the top piece of code posted here:

    ‘menu_order’,
    ‘container_class’ => ‘menu-header’,
    ‘theme_location’ => ‘primary’ ) ); ?>

    Is it supposed to go in a nav section of header.php by itself? As of now, all that is being output in the nav section is the code itse

    Comment by Marshall at 11:39 am on July 26, 2010

  9. Hi Marshall – Thanks for your comment – I realized that wordpress has botched my code sample – check out the updated sample – it goes into header.php and

    Comment by Paul Reilly at 4:27 pm on July 26, 2010

  10. Great stuff Paul, any ideas how to stop animation build up?
    I’ve tried adding .stop() before .animation() but it doesn’t
    work

    Comment by Igor at 2:29 pm on August 15, 2010

  11. Ok I think I found a solution, haven’t
    tested it in details for bugs, but it works
    instead of adding .stop() before .animation()
    add .filter(‘:not(:animated)’) just before
    the first .animate() so the code is :

    jQuery(document).ready(function($) {
    //initial the menus
    $(“ul.menu li”).mouseover(function() {
    $(this).find(“ul.sub-menu”).filter(‘:not(:animated)’).animate({“height”: “show”, “opacity”: “show”}, 800, “swing”);

    $(this).hover(function() {}, function(){
    $(this).find(“ul.sub-menu”).animate({“height”: “hide”, “opacity”: “hide”}, “slow”);
    });
    });
    });

    Comment by Igor at 3:19 pm on August 15, 2010

  12. Great stuff Igor! Thanks!

    Comment by Paul Reilly at 11:04 am on August 16, 2010

  13. What a solution! Works great & a needed feature to make updates easier on clients…

    Thanks guys.
    Jarome.

    Comment by Jarome at 10:32 pm on August 24, 2010

  14. Thank you ever so much… I’ve been looking for help like this, I’m not a newbie website developer but getting this new WP 3.0 menu to style the way I want it to was leaving me with crossed eyes and frustration.

    I appreciate very much that you not only say WHAT to do but WHY to do it that way.

    Wonderful post, thanks again.

    Comment by BeckyT at 12:07 pm on September 15, 2010

  15. Just a little trick with this menus. if you have 2 sub levels change all the

    ” $(this).find ” by “$(this).children”. and the menus will work fine.

    Comment by 6clicks at 11:59 am on November 15, 2010

  16. Hi, Paul.
    I’m new on wp design and man, I was searching around for its classes directions a long time and NOTHING. Great tutorial, thank you very much for sharing.

    Comment by Paulo Ramalho at 5:50 pm on December 12, 2010

  17. #

    Hi Seth – That’s something I came across as well and I don’t know of a way to fix it directly through WordPress. I would have thought they would allow you to pick it the link should load in an external window or not, similar to adding links in the editor.

    There is a workaround solution though – you can use jQuery to append the target = _blank parameter to all links that aren’t local to your site. Here’s a snippet that should do the trick:

    jQuery(“a[href^='http:']“).not(“[href*='mydomain.com']“).attr(‘target’,’_blank’);

    This is from http://trevordavis.net/blog/tutorial/use-jquery-to-open-all-external-links-in-a-new-window/

    Good luck!

    Comment by Paul Reilly at 4:02 pm on June 15, 2010
    ————-
    There actually is a way to set menu items to open in a new window via the WordPress Menu function…up in the right hand corner when you are in the menu editing section you can see a tab that says “Screen Options” click that and then select the button for “Link Target” and it will add a little selection for each menu item as to whether you want it opening in the same or a new window. Don’t know why WP is hiding that relatively useful function, but there it is.

    Comment by Kthune at 5:07 pm on March 1, 2011

  18. Thanks for this well put together guide. I’ll be linking to it soon.

    Comment by Mr WordPre$success at 9:41 pm on March 21, 2011

  19. [...] tutorial This entry was posted in Tutorials, WordPress. Bookmark the permalink. ← How to Code a [...]

    Pingback by Menu Tutorial | RAV's Blog at 2:27 am on March 31, 2011

  20. Hi Paul,

    thank you for this WP/CSS/jQ tutorial! Perhaps you could help with a bit of advice related to the same subject.

    I want to style the width of the submenus. For example, I have a TwentyTen custom menu of such structure:

    ABOUT
    Mission
    History
    People

    SERVICES
    Service1
    Service2
    Service3

    PRODUCTS
    Product1
    Product2
    Product3

    I want to make all items under ABOUT to be 200px wide; all items under SERVICES to be 250px wide, and all items under PRODUCTS to be 300px wide.

    How can I style them with CSS, considering that the menu is generated dynamically?

    Your suggestions would be most appreciated!

    Best,

    Dimitri Vorontzov

    Comment by Dimitri Vorontzov at 8:08 am on May 31, 2011

  21. Hi Dimitri, thanks for your interest in the post. I do not know of an easy way to do what you’re attempting. Two ideas come to mind though. First, if its just a matter of the items being at least a certain width, you can not set width on the LI and instead set padding/margins. This way the width will always be wider enough to accommodate your longest title.

    Second option would be to use javascript. You could use Jquery selectors to find the menu right after an LI with content of ‘ABOUT’ and dynamically set its width at load time.

    Good luck!

    Comment by Paul Reilly at 8:44 am on June 1, 2011

  22. Great tutorial.
    My problem that I have with my own navigation is how to style the nav menu so that each menu item gets a specific background color when you arrive at a certain page. Any ideas?

    Comment by iulian at 10:10 pm on August 27, 2011

  23. Hi iulian – Without knowing your plan in detail, you can probably solve this by giving css ids to your elements and then using jquery selectors to style it properly based on the page its on. I’d check up on how to use jquery css selectors. Good luck!

    Comment by Paul Reilly at 4:27 pm on August 28, 2011

  24. Help! I’m 99% there but the animation is showing up next to my main menu items. what is forcing the new block to the right? Thanks soo much for your tutorial!

    Comment by Kevin at 9:18 pm on September 13, 2011

  25. I’m curious to find out what blog system you happen to be utilizing? I’m experiencing some minor security issues with my latest site and I would like to find something more safeguarded. Do you have any recommendations?

    Comment by Senior Medical Alarms at 7:57 pm on November 1, 2011

  26. I just copy & paste the same code in tutorial to my site, but my menu doesn’t look like the one in video. how can i make exact menu like on video.

    Please help.

    Comment by Adam at 3:54 am on February 15, 2012

  27. Paul, thanks for the elegant know-how. I was wondering if this would work with the Twenty Eleven theme or not. The CSS seems identical but is there something else that needs amending to make it work?

    Comment by Heshan at 4:18 pm on March 28, 2012

  28. The menu works fine, thanks to your wonderful tutorial. But the problem I’m having is that the width of the submenus (when hovering over the top menu link) is causing the top menu link to also get wider (the same width as the submenu). This causes the whole top menu line to wrap onto a second line.

    How can I separate the widths of the submenus so they don’t affect the top menu? (i.e. …without making all the top menu items a static width.)

    Thanks!

    Comment by Karyn at 8:31 pm on July 4, 2012

  29. This works great, but I’m having trouble with my 3rd-tier menu items.

    When I mouseover menu item 2, both sub-sub-menu items 1+2 display. How can I make them stay hidden until I mouse over – sub-menu item 1?

    My menu stucture is:

    menu item 1
    – sub-menu item 1
    – sub-menu item 2

    menu item 2
    – sub-menu item 1
    – sub-sub-menu item 1
    – sub-sub-menu item 2
    – sub-menu item 2

    menu item 3
    – sub-menu item 1
    – sub-menu item 2

    Comment by Ando at 10:30 pm on September 4, 2012

  30. click here to investigate

    Using the WordPress 3.0 Menus Feature Part 2 – Styling and Animating | U-notez

    Trackback by click here to investigate at 4:21 am on September 24, 2014

  31. Keehnankonyha.com

    Using the WordPress 3.0 Menus Feature Part 2 – Styling and Animating | U-notez

    Trackback by Keehnankonyha.com at 7:45 am on September 24, 2014

Comments are closed for this post.

TrackBack URI

Unitz LLC, 850 North Randolph St., Suite 103 - A38, Arlington, VA  22203 * Tel. 703-539-2542 Email us