Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Below is an example. 3 classes attached to each item, except current item, which has 6. Can I pare this down somehow?

<ul id="menu-global-nav" class="sf-menu">
<li id="menu-item-63" class="menu-item menu-item-type-post_type current-menu-item page_item page-item-5 current_page_item menu-item-63"><a href="#">Home</a></li>
<li id="menu-item-30" class="menu-item menu-item-type-post_type menu-item-30"><a href="#">Services</a>
   <ul class="sub-menu">
   <li id="menu-item-39" class="menu-item menu-item-type-post_type menu-item-39"><a href="#">Case Studies</a></li>
   <li id="menu-item-38" class="menu-item menu-item-type-post_type menu-item-38"><a href="#">Story Discovery</a></li>
   </ul>
</li>
<li id="menu-item-32" class="menu-item menu-item-type-post_type menu-item-32"><a href="#">Company</a></li>
<li id="menu-item-29" class="menu-item menu-item-type-post_type menu-item-29"><a href="#">Why Case Studies?</a></li>
<li id="menu-item-28" class="menu-item menu-item-type-post_type menu-item-28"><a href="#">Case Study Showcase</a></li>
<li id="menu-item-27" class="menu-item menu-item-type-post_type menu-item-27"><a href="#">Resources</a></li>
<li id="menu-item-26" class="menu-item menu-item-type-post_type menu-item-26"><a href="#">Online Store</a></li>
<li id="menu-item-25" class="menu-item menu-item-type-post_type menu-item-25"><a href="#">Contact Us</a></li>
</ul>
share|improve this question
add comment

6 Answers 6

up vote 6 down vote accepted

I'm going against the majority on this one :)

Yes, it can be a good idea to strip it down. Personally I'm keeping only the current-xxx type classes and replacing them with active, and active-parent (for active parent or ancestor items).

Why?

  • around the web, active has became the standard class for active menu items (on top of that WP has inconsistent class naming conventions between its' own class names).
  • you get to write less CSS rules; the bandwidth that you save might not be much, but it certainly makes the CSS file more readable

Updated code:

// for custom menus 
add_filter('nav_menu_css_class', 'normalize_wp_classes', 10, 2);

// for the page menu fallback (wp_list_pages)
add_filter('page_css_class', 'normalize_wp_classes', 10, 2);

/**
 * @param  $classes array
 * @param  $item object
 * @return array
 */
function normalize_wp_classes(array $classes, $item = null){

  // old classes to be replaced with 'active'
  $replacements = array(
    'current-menu-item',
    'current-menu-parent',
    'current-menu-ancestor',
    'current_page_item',
    'current_page_parent',
    'current_page_ancestor',
  );

  // if any of the classes above are present,
  // return an array with a single class ('active')
  return array_intersect($replacements, $classes) ? array('active') : array();
}

Update: For anyone using this code, the active-parent class is no longer required (unless you still need IE 6 support). Using the child selector (>) you can effectively style the active parent and active child any way you want.

share|improve this answer
    
Could you share how you're stripping unwanted classes? –  Ray Gulick Nov 13 '11 at 4:28
    
Thanks for sharing your code, @One Trick Pony. I'll try this out on my next new install. What are the integers "10" and "2" for? Have seen that in other menu-related code; have never seen an explanation. –  Ray Gulick Nov 15 '11 at 18:43
    
filter priority (10 is default) and number of arguments passed to the hooked function if greater than 1. –  onetrickpony Nov 17 '11 at 2:04
    
Thanks for explaining that. –  Ray Gulick Nov 29 '11 at 17:40
add comment

The wp_nav_menu function gives you the ability to modify the ID and Class for both the container and the menu. But not the LI elements.

If you take a look at the source where it is building the LI elements ( start_el() function); You can see it is using the filter nav_menu_css_class; The filter will take the array you give it (of strings) and use it to build out the class tags.

Note: From what I see in the code, if you pass it an empty array. Wordpress will still include the class attribute for the LI element, it will just be empty.

share|improve this answer
add comment

All those classes are for useful hooking into javascript for something like superfish, not just because of IE6.

Also, without a class such as current_page_item, you wouldn't be able to highlight the current page within the navigation.

Flexibility is the key. Add all the classes, unique ones for unique items in the list, give the end designer a lot of flexibility in styling. But I do agree, that is a buttload of classes. A decent HTML programmer, designer could do the equivalent with much less code.

EDIT: Made it more clear what I meant, no disrespect intended

share|improve this answer
1  
I agree that JavaScript tools can work more effectively with multiple classes, but that's also one of the easiest ways to overcome IE6's lack of multi-selector support. To dismiss that use as "crazy talk" doesn't help anyone. –  EAMann Aug 12 '10 at 14:20
add comment

Modified from One Trick Pony's code as it didn't work for me with a current version of WP (3.5.1).

Added the dashed classes as WP now includes both underscored and dashed versions of the page hierarchy classes.

Changed array_diff -> array_intersect as diff returns all the classes instead of the filtered list.

// for custom menus
add_filter('nav_menu_css_class', 'normalize_wp_classes', 10, 2);

// for the page menu fallback (wp_list_pages)
add_filter('page_css_class', 'normalize_wp_classes', 10, 2);

/**
 * @param  $classes array
 * @param  $item object
 * @return array
 */
function normalize_wp_classes($classes, $item){

  // old class => new class
  $replacements = array(
    'current-menu-item'     => 'active',
    'current-menu-parent'   => 'active-parent',
    'current-menu-ancestor' => 'active-parent',
    'current_page_item'     => 'active',
    'current_page_parent'   => 'active-parent',
    'current_page_ancestor' => 'active-parent',
    'current-page-item'     => 'active',
    'current-page-parent'   => 'active-parent',
    'current-page-ancestor' => 'active-parent'
  );

  // do the replacements above
  $classes = strtr(implode(',', $classes), $replacements);
  $classes = explode(',', $classes);

  // remove any classes that are not present in the replacements array,
  // and return the result

  return array_unique(array_intersect(array_values($replacements), $classes));
}
share|improve this answer
add comment

I wouldn't recommend paring it down. Yes, the markup might look bloated, but this is the only way you can really narrow down the styling if you want your site to look good in, say, IE6. Keep in mind that IE6 doesn't natively support multiple selectors (i.e. li.menu-item.current will break and default to li.current), so if you're doing any fancy CSS and want it to work with IE6, it's better to have a lot of class selectors available than not enough.

So, in reality, you could pare the list down to class="menu-item" ... but if you're going to ever have a menu with more than one post type, you'll need menu-item-type-post_type ... and if you want to do fancier filtering, you'll benefit from the menu-item-## class as well.

Remember, no one will likely ever see the actual code behind your site, and having multiple classes defined won't hurt anything.

share|improve this answer
1  
The ONLY way to manage styling for IE6 is a minimum of 3 classes per list item? I think not. –  Ray Gulick Aug 11 '10 at 20:20
    
Not the only way, but it's the best hack-free alternative to multiple selectors. If you're OK with using non-standard CSS hacks or depending on JavaScript to fix IE6's shortcomings, then there are alternatives. –  EAMann Aug 11 '10 at 20:29
    
So, if I "could" pare down the classes, how? –  Ray Gulick Aug 15 '10 at 21:58
add comment

@Ray Gulick: I hate to dive in but I concur with @Dan Gale, @EAMann and @Insanity5902. The "bloat" doesn't cause any tanbgible problems and enables a designer to theme the menu in a lot of flexible ways.

I'm curious why the "bloat" bothers you? I know it's not pretty but next to nobody will ever see it. If its a performance concern that are hundreds of other things to address first such as reducing HTTP requests and shaving the sizes of your images the latter of which will probably have an order of magnitude more benefit.

share|improve this answer
    
I dislike it because it's basically useless garbage. 2 classes would be fine on a list item. But 6? Pretty ridiculous. Do you know if these classes can be controlled or specified in the functions file? –  Ray Gulick Aug 15 '10 at 19:28
    
@Ray Gulick: But in the grand scheme, does it really matter? Just sayin... –  MikeSchinkel Aug 16 '10 at 2:35
    
In the grand scheme we're all dust in the wind, but in the meantime, I'd like to be in control of what classes show up on my list items. Doesn't seem like a lot to ask for ;-) –  Ray Gulick Aug 18 '10 at 19:33
    
It comes down to either having streamlined solution that require customize development or solutions that include more than is needed but are more flexible and easier to support a wider array of needs. One is not better than the other, just optimized for different purposes. You can have what you want with WordPress, you'll just have to write your own menu generator. –  MikeSchinkel Aug 18 '10 at 20:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.