Add Sub Headings to WordPress Menu

WordPress has done an excellent job with the Menu structure and the ability to edit it. Recently I have been converting a lot of PSD to WordPress sites which will be going up on my feedback page for you to see. There are some options in WordPress that are not naively active and must be enabled manually. This one will allow you to add a description to your menu’s like you see on my site and on Pat Flynn’s Smart passive income blog. Follow these steps to brighten up your WordPress menu.

Step 1

Log in to your WordPress admin panel and make your way to Appearance > Menu

At the top right you will see a small tab called screen options. Click on it and select Description like so and save.

display menu description wordpress

Note: Some themes support this natively, so first try adding a description to your menu by selecting one of your menus and opening it, you should now see a description box. Add a description and save. Then go to your site and press control F5 to clear cache on your browser and see if the description appears.

add a description to wordpress menu

If nothing Appears proceed to step 2

Step 2

Using either FTP or your file manager on your server find your functions.php file.

For Thesis Users locate custom_functions.php found in the custom folder.

Paste this code in and save.

class Menu_With_Description extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;

        $indent = ( $depth ) ? str_repeat( " ", $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        ) .'"' : '';

		// get user defined attributes for thumbnail images
		$attr_defaults = array( 'class' => 'nav_thumb' , 'alt' => esc_attr( $item->attr_title ) , 'title' => esc_attr( $item->attr_title ) );
		$attr = isset( $args->thumbnail_attr ) ? $args->thumbnail_attr : '';
		$attr = wp_parse_args( $attr , $attr_defaults );

        $item_output = $args->before;

		// thumbnail image output
		$item_output .= ( isset( $args->thumbnail_link ) && $args->thumbnail_link ) ? '<a' . $attributes . '>' : '';
		$item_output .= apply_filters( 'menu_item_thumbnail' , ( isset( $args->thumbnail ) && $args->thumbnail ) ? get_the_post_thumbnail( $item->object_id , ( isset( $args->thumbnail_size ) ) ? $args->thumbnail_size : 'thumbnail' , $attr ) : '' , $item , $args , $depth );		
		$item_output .= ( isset( $args->thumbnail_link ) && $args->thumbnail_link ) ? '</a>' : '';

		// menu link output
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;

		// menu description output based on depth
        $item_output .= ( $args->desc_depth >= $depth ) ? '<br /><span class="sub">' . $item->description . '</span>' : '';

		// close menu link anchor
        $item_output .= '</a>';
        $item_output .= $args->after;

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

add_filter( 'wp_nav_menu_args' , 'my_add_menu_descriptions' );
function my_add_menu_descriptions( $args ) {
	$args['walker'] = new Menu_With_Description;
	$args['desc_depth'] = 0;
	$args['thumbnail'] = true;
	$args['thumbnail_link'] = false;
	$args['thumbnail_size'] = 'nav_thumb';
	$args['thumbnail_attr'] = array( 'class' => 'nav_thumb my_thumb' , 'alt' => 'test' , 'title' => 'test' );

	return $args;

This script will rebuild your menu to include your description for themes that don’t naively support it.

I hope this has been helpful and please send me your feedback, I don’t own every theme so it’s a little tough to test on them all.

Step 3

Some CSS to get you going, I can’t make a set piece of CSS because every blog will be different but this should get you started.

.sub {
    font-size: 10px;

Final step

Well that’s its really, you might need to do some styling.

Subscribe today and receive all the Latest posts and tips for Thesis and other WordPress themes.

Meet the Author

Matthew Horne

Matthew Horne is web developer who specializes in optimized development. He also builds custom solutions instead of reverting to plugins. Matthew Has a strong understanding of PHP, JavaScript, jQuery.

11 comments… add one
  • Rahn Aug 7, 2012, 11:11 am

    Hey Matt,
    it worked!
    I had never paid attention to the screen options before. I had added descriptions to my categories when I created them, thinking it was a memo for me to remember why I created the category.
    I had to add the functions in order to get it to work with the Suffusion theme. If you don’t want to deal with FTP, you can edit the functions.php file directly in WordPress under Themes->Editor, then search for “functions.php” on the page. You don’t get to keep a backup, so you need to pay attention to what you’re doing. But much easier to do for a quickie like this.

    Now, to go take the descriptions back out, until I decide to mess with the css.

    • Horne3754sg Aug 7, 2012, 11:49 am

      Thanks for your input, yes you can edit via the wordpress editor but if you make a mistake you would have to use ftp or the filemanager as the error will prevent you being able to reverse or correct it. I always advice people to edit outsite of wordpress when it comes to php files.

  • ponsanand Feb 7, 2013, 1:49 pm

    awesome… thanks

  • Atanas Aug 22, 2013, 7:32 pm

    I am trying to follow ur steps. I added the mentioned code in my Thesis’s customs function file, but cant understand where I should add the CSS .sub and 10 for font.. I added the last on in my custom.css and nothing happened… Please help. I like to add some text just like the extra text in my menu just like the Pat’s blog SPI ….

  • Atanas Aug 22, 2013, 7:42 pm

    Problem was solved – Just go to Thesis – Design Options – > Navigation Menu and I changed the Nav bar menu from Thesis to Wordpress. Now its Ok… Just wondering where I should touch in the code to edit the added extra text, I mean fonts, size and other.. As you mentioned. Some little CSS advice? Thx

    • Matthew Horne Aug 24, 2013, 12:07 pm

      Glad you got it working there. The class is .sub so you can use that class to style it in any way you see fit.


  • Joe Corneli Aug 23, 2013, 9:24 pm

    Thanks, this worked for me. I saw some similar instructions elsewhere that didn’t – so, good job! However, I did have to add one small fix. In the first few lines:

    $indent = ( $depth ) ? str_repeat( $depth ) : ”;

    should be something like

    $indent = ( $depth ) ? str_repeat( ” “, $depth ) : ”;


  • Atik Jan 4, 2014, 3:04 pm


  • Venkatesh Sep 25, 2014, 1:42 pm

    Cool!!!!!!!!!! Thank You for your Description I like it.and thanks for my prblm solving….

Leave a Comment