Coastal Media Brand

Create a Menu

First things first, in the functions.php of our theme (as usual, mine is called Playground), we’ll register a new navigation menu location:

1
function playground_setup() {
2
    //Register menu locations
3
    register_nav_menus(
4
        array(
5
            'header-menu' => __( 'The Header Menu', 'playground' ),
6
            //more locations here
7
        )
8
    );
9
}
10
add_action( 'after_setup_theme', 'playground_setup' );

Through the admin, we’ll create a new menu and associate it with this location:

Our header menuOur header menu

Next, we’ll display that menu everywhere we want by using the wp_nav_menu() function and passing as the value of the theme_location key the location we created.

In our example, this will be the primary menu and sit on the header.

Here’s the header code—our logo will come from an SVG Sprite like we discussed in a previous tutorial: 

1
<header class="site-header">
2
    <nav>
3
        <a class="logo" href="<?php echo esc_url( home_url( '/' ) ); ?>" aria-label="forecastr logo">
4
            <svg width="178" height="38" role="img">
5
                <use href="#logo"></use>
6
            </svg>
7
        </a>
8
        <?php
9
        wp_nav_menu(
10
            array(
11
                'container'      => false,
12
                'theme_location' => 'header-menu',
13
            )
14
        );
15
        ?>
16
    </nav>
17
</header>

Style the Header With CSS

Here’s the header appearance:

The header apperance with Feather iconsThe header apperance with Feather iconsThe header apperance with Feather icons

To achieve this layout, we’ll need the following styles:

1
:root {
2
  --white: #fff;
3
  --orange: #e76f51;
4
  --lightyellow: #fcf5e4;
5
}
6

7
.site-header {
8
  position: sticky;
9
  top: 0;
10
  padding: 3vh 0;
11
  z-index: 1;
12
  background: var(--lightyellow);
13
}
14

15
.site-header nav {
16
  display: flex;
17
  align-items: center;
18
  justify-content: space-between;
19
  padding: 0 20px;
20
}
21

22
.site-header .logo svg {
23
  fill: var(--orange);
24
}
25

26
.site-header .menu {
27
  list-style: none;
28
  padding: 0;
29
  margin: 0;
30
  justify-content: center;
31
  gap: 20px;
32
}
33

34
.site-header .menu,
35
.site-header .menu li,
36
.site-header .menu a {
37
  display: inline-flex;
38
}
39

40
.site-header .menu a {
41
  align-items: center;
42
  gap: 5px;
43
  text-decoration: none;
44
  font-size: 22px;
45
  padding: 0 10px;
46
  border-radius: 5px;
47
  border: 2px solid transparent;
48
  transition: border 0.15s ease-out;
49
}
50

51
.site-header .menu svg,
52
.site-header .menu path {
53
  fill: var(--orange);
54
}
55

56
.site-header .menu .current-menu-item a,
57
.site-header .menu a:hover {
58
  border-color: var(--orange);
59
}

Make a Plan

Let’s now make our menu more attractive by adding one icon to each menu item. There are different ways of doing it, for example:

Here we’ll go with the second option.

If you search for this filter in the WordPress files, you’ll find it in the wp-includes/nav-menu-template.php file path.

Where the wp_nav_menu_objects filter existsWhere the wp_nav_menu_objects filter existsWhere the wp_nav_menu_objects filter exists

The goal is to add a callback function to that filter that will only modify the header menu items.

So, in the functions.php, we’ll place a starting code similar to this:

1
function modify_nav_menu_args( $sorted_menu_items, $args ) {
2
    if ( 'header-menu' === $args->menu->slug ) :
3
        foreach ( $sorted_menu_items as $item ) :
4
            //do something
5
        endforeach;
6
    endif;
7

8
    return $sorted_menu_items;
9
}
10
add_filter( 'wp_nav_menu_objects', 'modify_nav_menu_args', 10, 2 );

For dev purposes, we can print in the front end the $sorted_menu_items and $args parameters.

To make this process as understandable as possible, we’ll add icons in four different ways.

Icons from the Font Awesome Library

Let’s first discuss how to include Font Awesome icons in our menu. For simplicity, we’ll load this library through a CDN like this:

1
//functions.php
2

3
function playground_scripts_and_styles() {
4
    wp_enqueue_script( 'fa-icons', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/js/all.min.js');
5
    ...
6
}
7
add_action( 'wp_enqueue_scripts', 'playground_scripts_and_styles' );

Next, we’ll place the desired icon classes for each menu item in the description field—this field isn’t printed by default in the code unless we force it.

How to add a Font Awesome iconHow to add a Font Awesome iconHow to add a Font Awesome icon

Back to our callback function, we’ll use an i tag to display the description of each menu item—feel free to add aria-hidden="true" if you want: 

1
//functions.php
2

3
function modify_nav_menu_args( $sorted_menu_items, $args ) {
4
    if ( 'header-menu' === $args->menu->slug ) :
5
        foreach ( $sorted_menu_items as $item ) :
6
            if ( $item->description ) :
7
                $item->title = '<i class="' . $item->description . '"></i>' . $item->title;
8
            endif;
9
        endforeach;
10
    endif;
11

12
    return $sorted_menu_items;
13
}
14
add_filter( 'wp_nav_menu_objects', 'modify_nav_menu_args', 10, 2 );

In the browser console, we’ll see something like this:

The generated icon as shown in the browser consoleThe generated icon as shown in the browser consoleThe generated icon as shown in the browser console

The end result will look like this—the first item shows the hover and active states:

The header apperance with Font Awesome iconsThe header apperance with Font Awesome iconsThe header apperance with Font Awesome icons

Icons from the Feather Collection

Moving on, let’s learn how to embed icons through the Feather icon collection. Again, for simplicity, we’ll load this collection through a CDN like this:

1
//functions.php
2

3
function playground_scripts_and_styles() {
4
    wp_enqueue_script( 'feather-icons', ' );
5
    ...
6
}
7
add_action( 'wp_enqueue_scripts', 'playground_scripts_and_styles' );

As we’ve done with the Font Awesome icons, we’ll place the desired icon name for each menu item in the description field.

How to add a Feather iconHow to add a Feather iconHow to add a Feather icon

Back to our callback function, we’ll use an i tag to display the description of each menu item. Notice the presence of the data-feather icon that the library requires, as mentioned in the instructions.

1
 function modify_nav_menu_args( $sorted_menu_items, $args ) {
2
    if ( 'header-menu' === $args->menu->slug ) :
3
        foreach ( $sorted_menu_items as $item ) :
4
            if ( $item->description ) :
5
                $item->title = '<i data-feather="' . $item->description . '"></i>' . $item->title;
6
            endif;
7
        endforeach;
8
    endif;
9
    
10
    return $sorted_menu_items;
11
}
12
add_filter( 'wp_nav_menu_objects', 'modify_nav_menu_args', 10, 2 );

Last but not least, in our JavaScript, we’ve to call the feather.replace() method to associate the icon names with the actual SVG icons.

In the browser console, we’ll see something like this:

The generated icon as shown in the browser consoleThe generated icon as shown in the browser consoleThe generated icon as shown in the browser console

The end result will look like this—the first item shows the hover and active states:

The header apperance with Feather iconsThe header apperance with Feather iconsThe header apperance with Feather icons

Custom Icons

All that seems great, but what if we want to use custom icons? In such a case, we’ve different options. Let’s see two of them in action.

Upload Icons to the Media Library

One option is to upload all icons to the media library and then pass their image attachment ID in the menu description.

For example, in our case, I’ve uploaded the same SVG Feather icons we used before.

The Feather icons uploaded to the WordPress media libraryThe Feather icons uploaded to the WordPress media libraryThe Feather icons uploaded to the WordPress media library

Make sure to enable SVG support to your WordPress site. You can do it by code or by installing a plugin like SVG Support.

In my case, the attachment ID for the home icon is 47.

How to add a custom iconHow to add a custom iconHow to add a custom icon

Then, in the callback, we’ll use the wp_get_attachment_image() function to grab all the info for this icon.

1
function modify_nav_menu_args( $sorted_menu_items, $args ) {
2
    if ( 'header-menu' === $args->menu->slug ) :
3
        foreach ( $sorted_menu_items as $item ) :
4
            if ( $item->description ) :
5
                $item->title = wp_get_attachment_image( $item->description, 'full', true ) . $item->title;
6
            endif;
7
        endforeach;
8
    endif;
9
    
10
    return $sorted_menu_items;
11
}
12
add_filter( 'wp_nav_menu_objects', 'modify_nav_menu_args', 10, 2 );

Depending on how large are your icons, you might want to render a different image size.

In the browser console, we’ll see something like this:

The generated icon as shown in the browser consoleThe generated icon as shown in the browser consoleThe generated icon as shown in the browser console

The end result will look like this:

The header apperance with custom iconsThe header apperance with custom iconsThe header apperance with custom icons

Notice that the icon’s fill color doesn’t change on the hover and active states as it’s rendered as an image and not SVG.

Create a New Field – ACF Plugin

Another option is to use a plugin like the Advanced Custom Fields (ACF) WordPress plugin for adding a new image field to the menu items.

This case is more convenient in case you want to display the description field and need another field for the icon.

Through the settings, we’ll specify as the return type the Image ID and not the default Image Array

The return type of our iconThe return type of our iconThe return type of our icon

Then, we’ll upload the desired icon:

And finally, we’ll use ACF’s get_field() function to output the target icons:

1
//functions.php
2

3
function modify_nav_menu_args( $sorted_menu_items, $args ) {
4
    if ( 'header-menu' === $args->menu->slug ) :
5
        foreach ( $sorted_menu_items as $item ) :
6
            $icon_id = get_field( 'icon', $item );
7
            if ( $icon_id ) :
8
                $item->title = wp_get_attachment_image( $icon_id, 'full', true ) . $item->title;
9
            endif;
10
        endforeach;
11
    endif;
12
    
13
    return $sorted_menu_items;
14
}
15
add_filter( 'wp_nav_menu_objects', 'modify_nav_menu_args', 10, 2 );

The generated code and result are exactly the same as before:

The generated icon as shown in the browser consoleThe generated icon as shown in the browser consoleThe generated icon as shown in the browser console
The header apperance with custom iconsThe header apperance with custom iconsThe header apperance with custom icons

Conclusion

Done, folks! I hope you now have a good understanding of how to make your WordPress navigation menus more appealing by incorporating icons from different icon libraries, or even your custom ones!

Stay tuned as more WordPress content is coming.. As always, thanks a lot for reading!

Coastal Media Brand

© 2024 Coastal Media Brand. All rights Reserved.