How to apply a class to the second word in menu list item?

I want to apply a class to a word in my menu. For example, say I have a list item in my menu called “My Item”. I would like to apply a class to the word “Item” so that I can style it anyway I want.

Do I need to add a span to the list item and then add the class to my css like this?

<div id="nav">
    <ul>
        <li><a href="/MyItem">My <span class="dark-blue">Item</span></a></li>
    </ul>
</div>

#nav ul li a.dark-blue {
    color: #00008B;
}

Related posts

Leave a Reply

1 comment

  1. You can filter the title of each nav menu item. Unfortunately, the filter is named 'the_title' – if we just add a simple filter for it, we may catch strings outside of nav menus too.

    So we need a second function to switch our nav menu title filter on when the menu class starts and off when it ends.

    Let’s start with the second function:

    add_filter( 'wp_nav_menu_args', 'wpse_14037_filter_switch' );
    add_filter( 'wp_nav_menu', 'wpse_14037_filter_switch' );
    
    /**
     * Switches the registration of out title filter on and off.
     *
     * @param  mixed $input Array or string, we just pass it through.
     * @return mixed
     */
    function wpse_14037_filter_switch( $input )
    {
        $func = 'wp_nav_menu_args' == current_filter() ? 'add_filter' : 'remove_filter';
        $func( 'the_title', 'wpse_14037_filter_title' );
        return $input;
    }
    

    'wp_nav_menu_args' is called in wp_nav_menu() very early. When wpse_14037_filter_switch() is running in this context (current_filter) we turn the title filter on.

    'wp_nav_menu' is called after all item are rendered. Now we turn the title filter off.

    Now we need the wpse_14037_filter_title() we just registered:

    /**
     * Adds a <span class="partNUMBER"> to each word of a menu item title.
     *
     * @param  string $title
     * @return string
     */
    function wpse_14037_filter_title( $title )
    {
        $title = trim( $title );
        $parts = explode( ' ', $title );
        $out   = array ();
        $i     = 1;
    
        foreach ( $parts as $part )
        {
            $out[] = '<span class="part' . $i++ . '">' . $part . '</span>';
        }
    
        return join( ' ', $out );
    }
    

    I decided to make the function more generic than you wanted it. Other people may want to style the third word … or the 15th.

    To address the second word in your stylesheet just use the new class:

    /* Your menu may have the class 'menu'. */
    .menu .part2
    {
        color: #005;
    }