70

I am using wp_nav_menu($args) and I want to add my_own_class CSS classname to the <li> element.

I'd like to get the following result:

<li class='my_own_class'><a href=''>Link</a>

How to do that?

Ruvee
  • 8,611
  • 4
  • 18
  • 44
Ayyaz Zafar
  • 2,015
  • 5
  • 26
  • 40
  • This function is very well documented, but it appears a lot easier to add a class to the ul or wrap the link content with something and change your CSS accordingly (custom walker is you alternative): http://codex.wordpress.org/Function_Reference/wp_nav_menu – C. E. Jan 22 '13 at 18:10
  • Or..you could create your own Menu Walker ( [Codex](https://developer.wordpress.org/reference/classes/walker_nav_menu/) ) and use it in your `wp_nav_menu()` function.. – Erenor Paz Apr 25 '18 at 09:21

15 Answers15

170

No need to create custom walker. Just use additional argument and set filter for nav_menu_css_class.

For example:

$args = array(
    'container'     => '',
    'theme_location'=> 'your-theme-loc',
    'depth'         => 1,
    'fallback_cb'   => false,
    'add_li_class'  => 'your-class-name1 your-class-name-2'
    );
wp_nav_menu($args);

Notice the new 'add_li_class' argument.

And set the filter on functions.php

function add_additional_class_on_li($classes, $item, $args) {
    if(isset($args->add_li_class)) {
        $classes[] = $args->add_li_class;
    }
    return $classes;
}
add_filter('nav_menu_css_class', 'add_additional_class_on_li', 1, 3);
Zunan
  • 1,935
  • 1
  • 7
  • 11
  • 6
    Nice solution. If I was the OP, I would have accepted this as the answer. – Peyman Mohamadpour Jan 11 '19 at 19:01
  • 1
    Best solution IMO, generic and clean – Sogeking May 08 '19 at 10:29
  • 3
    Best solution, but I need to modify it to avoid an error "Undefined property: stdClass::$item_class" **Solution**: if(isset($args->item_class)) { ...etc – Stuart Cusack Aug 09 '19 at 11:11
  • 1
    what is the function of 1 and 3 argument? Please Explain. – Mirajul Momin Jul 02 '20 at 05:26
  • 1 is the priority order. Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. 3 is the number of arguments the function accepts. On that case, the filter will accept $classes, $items and $args arguments. Please read https://developer.wordpress.org/reference/functions/add_filter/ for more information – Zunan Jul 02 '20 at 05:59
  • 1
    This didn't work for me. Instead of `isset($args->add_li_class)` I had to add `array_key_exists('add_li_class', $args)`. And for `$classes[] = $args->add_li_class;` I had to add `$classes[] = $args['add_li_class'];`. – SplitterAlex Feb 16 '21 at 08:35
76

You can add a filter for the nav_menu_css_class action in your functions.php file.

Example:

function atg_menu_classes($classes, $item, $args) {
  if($args->theme_location == 'secondary') {
    $classes[] = 'list-inline-item';
  }
  return $classes;
}
add_filter('nav_menu_css_class', 'atg_menu_classes', 1, 3);

Docs: https://developer.wordpress.org/reference/hooks/nav_menu_css_class/

allicarn
  • 2,859
  • 2
  • 28
  • 47
Andres F Garcia
  • 6,795
  • 1
  • 14
  • 9
  • 7
    I know this answer was published much later than the chosen one, but I feel this should be marked as the correct answer as it does exactly what the question asked. – Richard Hedges Feb 07 '17 at 15:37
  • I couldn't get this to work, directly copied into my functions.php and it doesn't do anything. – Spencer Shattuck Apr 05 '18 at 07:50
  • 1
    @SpencerShattuck do you have a menu location 'secondary' in your theme? You may also need something like register_nav_menus( array( 'primary' => __( 'Primary Menu' ), 'secondary' => __( 'Secondary Menu' ) ) ); – Andres F Garcia Apr 12 '18 at 15:08
  • I found a solution that worked for me at: https://github.com/wp-bootstrap/wp-bootstrap-navwalker – Spencer Shattuck Apr 12 '18 at 17:14
68

HERE WordPress add custom class in wp_nav_menu links

OR you can add class <li class='my_own_class'><a href=''>Link</a></li> from admin panel:

  1. Go to YOURSITEURL/wp-admin/nav-menus.php

  2. open SCREEN OPTIONS

  3. make checked CSS CLASSES, then you will see CSS Classes (optional) field in each menu link.
Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
Rameez SOOMRO
  • 1,529
  • 15
  • 24
17

Adding Class to <li> tag without editing functions.php file:

  1. Go to Appearance -> Menu -> Screen Options -> CSS Classes
  2. You will get CSS Class option enabled in Menu Items Window

enter image description here

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
Trupti
  • 627
  • 5
  • 9
15

use this filter nav_menu_css_class as shown below

function add_classes_on_li($classes, $item, $args) {
    $classes[] = 'nav-item';
    return $classes;
}
add_filter('nav_menu_css_class','add_classes_on_li',1,3);

UPDATE

To use this filter with specific menu

if ( 'main-menu' === $args->theme_location ) { //replace main-menu with your menu
    $classes[] = "nav-item"; 
}
Regolith
  • 2,944
  • 9
  • 33
  • 50
  • But how to we target specific menus with this approach. I have a menu called main-menu and another called footer-menu. – klewis Jan 08 '19 at 04:24
  • 3
    try wrapping `$classes[] = "nav-item";` with `if ( 'main-menu' === $args->theme_location ) { $classes[] = "nav-item"; }` – Regolith Jan 08 '19 at 05:52
6

How about just using str_replace function, if you just want to "Add Classes":

<?php
    echo str_replace( '<li class="', '<li class="myclass ',
        wp_nav_menu(
            array(
                'theme_location'    => 'main_menu',
                'container'         => false,
                'items_wrap'        => '<ul>%3$s</ul>',
                'depth'             => 1,
                'echo'              => false
            )
        )
    );
?>

Tough it is a quick fix for one-level menus or the menus that you want to add Classes to all of <li> elements and is not recommended for more complex menus

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
Amin
  • 1,637
  • 1
  • 22
  • 40