$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>Add Class to Specific Link in Custom Menu|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Add Class to Specific Link in Custom Menu

matteradmin8PV0评论

I know you can add a class in the custom menu options, but it adds it to the LI before the A. I want to apply the class directly to this specific A rather then the whole LI.

So instead of the output being

<li id="menu-item-51" class="NEWCLASS menu-item menu-item-type-custom menu-item-51"><a href="#">Link</a> </li>

I want it too be like this.

<li id="menu-item-51" class="menu-item menu-item-type-custom menu-item-51"><a href="#" class="NEWCLASS">Link</a></li>

Any ideas?

I know you can add a class in the custom menu options, but it adds it to the LI before the A. I want to apply the class directly to this specific A rather then the whole LI.

So instead of the output being

<li id="menu-item-51" class="NEWCLASS menu-item menu-item-type-custom menu-item-51"><a href="#">Link</a> </li>

I want it too be like this.

<li id="menu-item-51" class="menu-item menu-item-type-custom menu-item-51"><a href="#" class="NEWCLASS">Link</a></li>

Any ideas?

Share Improve this question edited Feb 23, 2011 at 12:53 Rarst 100k10 gold badges161 silver badges298 bronze badges asked Feb 22, 2011 at 20:12 user3407user3407 4
  • Just to be clear, what do you mean by adding class? What options do you exactly click in the admin panel? – Wordpressor Commented Feb 22, 2011 at 20:17
  • 2 What's the point of that? Just change your selector from .class to .class a? – wyrfel Commented Feb 22, 2011 at 21:06
  • 1 Yeah i don't get it either, just set your CSS to target the link based on the containing <li> element. If you have a submenu below that particular item it's no problem, you can tackle that in the CSS to(i can give examples if necessary). – t31os Commented Feb 22, 2011 at 21:36
  • +1 for your comment @wyrfel ... @Picard102 take a look at css specifity. this will also explain you how to properly target html elements via css. – kaiser Commented Mar 25, 2011 at 13:51
Add a comment  | 

7 Answers 7

Reset to default 11

you can use nav_menu_css_class filter

add_filter('nav_menu_css_class' , 'my_nav_special_class' , 10 , 2);
function my_nav_special_class($classes, $item){
    if(your condition){ //example: you can check value of $item to decide something...
        $classes[] = 'my_class';
    }
    return $classes;
}

Using this $item you can any condition you want. and this will add the class to the specific li and you can style the a tag based on that like so:

.my_class a{
   background-color: #FFFFFF;
}

I found a solution at this site through the use of a custom walker.

Two steps: replace the default wp_nav_menu code with an edited one, and then add code to the functions.php of the theme.

First, replace the default wp_nav_code with the following (the code is copied from the above site):

    wp_nav_menu( array(
     'menu' => 'Main Menu',
     'container' => false,
     'menu_class' => 'nav',
     'echo' => true,
     'before' => '',
     'after' => '',
     'link_before' => '',
     'link_after' => '',
     'depth' => 0,
     'walker' => new description_walker())
     );

Next, add the following code to functions.php. By doing this you can actually add a class to the menu links:

class description_walker extends Walker_Nav_Menu
{

  function start_el(&$output, $item, $depth, $args)
  {
       global $wp_query;
       $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

       $class_names = $value = '';

       $classes = empty( $item->classes ) ? array() : (array) $item->classes;

       $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
       $class_names = ' class="'. esc_attr( $class_names ) . '"';

       $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

       $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
       $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
       $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
       $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

       $prepend = '<strong>';
       $append = '</strong>';
       $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

       if($depth != 0)
       {
                 $description = $append = $prepend = "";
       }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
        $item_output .= $description.$args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

                    if ($item->menu_order == 1) {
            $classes[] = 'first';
        }

        }
}

Towards the end of the code are several lines that start with $item_output. In particular, you want to look at this piece:

$item_output .= '<a'. $attributes .'>';

Because this line determines the output for the beginning of the link html. If you change it to something like this:

$item_output .= '<a'. $attributes . 'class="abc"' .'>';

Then all your links in the menu will have class="abc" added to them.


That said, it doesn't allow a custom class for each link (or at least I don't know how to code it). This is an issue for me.

For those asking why would you want to do this? I want to have my menu links open lightboxes (colorboxes, to be more specific), and they require classes on the links to do that. For example:

<a class="lightbox1" href="#">Photo</a>

Is there possibly a way to dynamically generate the classes, such as "lightbox1" for the first link, "lightbox2" for the second link, and so on?

SOLVED!!!! I needed to figure this out to make the menu item link to inline HTML in a fancybox. Paste the following code into your theme's function.php:

function add_menuclass($ulclass) {
    return preg_replace('/<a rel="fancybox"/', '<a class="fancybox"', $ulclass, -1);
}
add_filter('wp_nav_menu','add_menuclass');

Then... in the Menu tab of the WP Dashboard, create a custom link, add it to your menu. On the top where is says Screen Options, make sure you have "Link Relationship (XFN)" checked. It will add that field to your custom menu item. Type "fancybox" (without quotes) into the field and save your menu.

The function looks for the call to the navigation menu, then finds wherever you have a rel="fancybox" and replaces it with a rel="fancybox" class="fancybox". You can replace fancybox with whatever class you need to add to your menu items. Done and done!

Current answers don't seem to recognize that the question is how to add a class to the a element and not the li element, or are too complicated. Here's a simple approach using the nav_menu_link_attributes filter that allows you to target a specific menu based on it's slug and a specific page link in that menu based on it's ID. You can var_dump $args and $item to get more ways to create your condition.

add_filter('nav_menu_link_attributes', 'custom_nav_menu_link_attributes', 10, 4);

function custom_nav_menu_link_attributes($atts, $item, $args, $depth){
    if ($args->menu->slug == 'your-menu-slug' && $item->ID == 1){

        $class = "button";

        // Make sure not to overwrite any existing classes
        $atts['class'] = (!empty($atts['class'])) ? $atts['class'].' '.$class : $class; 
    }

    return $atts;
}

I know this was answered a long time ago, but just as general info, I found how to add a class to each menu item individually using the "Screen" option of the WordPress admin page for Custom Menus.

I had to do something similar recently and figured out another way. I had to add a similar class for a Nivo lightbox plugin. So I added "nivo" to the rel attribute ("Link Relationship (XFN)") and then the following on the nav_menu_link_attributes filter.

function add_nivo_menuclass($atts, $item, $args) {
    if( is_array($atts) && !empty($atts['rel']) && $atts['rel'] = 'nivo' ) {
        $atts['class'] = 'lightbox';
        $atts['data-lightbox-type'] = 'inline';
    }

    return $atts;

    }
add_filter('nav_menu_link_attributes','add_nivo_menuclass', 0,3);

In the upper area of Appearance -> Menus page, click to expand the Screen Options, check the checkbox of CSS Classes. Now when you expand each of the added menu item, you'll see a CSS Classes (optional) field.

Articles related to this article

Post a comment

comment list (0)

  1. No comments so far