Adding Dropdown Arrow Indicators With Font Awesome

I am using the 4.7 version for this tutorial, not the latest 5.0+ version as it works fine for my needs. If you want to use the latest version – you should just need to change the class names from fa to fas

In today’s tutorial, we are going to make a main navigation area more user friendly by indicating if any parent nav items contain a hidden sub menu that will come into view on hover. We will indicate this to the user by adding a subtle arrow next to the menu item. We could do this in a number of ways but I will be using the Font Awesome library to help me out.

Setting up Font Awesome

We are going to be lazy here and use a CDN to pull in Font Awesome – so let’s get started by including the following CSS file into our HTML page.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

Navigation markup

Next, we are going to create our basic navigation HTML with sub menu.

<nav id="primary-nav"> 
   <ul id="menu-primary-nav"> 
      <li><a href="#">Home</a></li> 
      <li class="has-submenu"><a href="#">About</a> 
         <ul class="sub-menu"> 
            <li><a href="#">Testimonials</a></li> 
         </ul> 
      </li> 
      <li><a href="#">Portfolio</a></li> 
      <li><a href="#">Contact</a></li> 
   </ul> 
</nav>

Styling up the navigation menu

Here is my basic CSS for the navigation menu. And as this tutorial is only about adding dropdown arrows to nav items that have sub menus, I won’t be styling the sub menu and will just hide it for this tutorial.

* { 
  margin: 0;   
  padding: 0; 
  box-sizing: border-box;
  font-family: sans-serif; 
}
nav#primary-nav {
   border: 1px solid #ccc;
   width: 100%;
   float: left;
}
   nav#primary-nav li {
      list-style: none;
      position: relative;
      border-right: 1px solid #ccc;
   }
      nav#primary-nav a {
         display: block;
         padding: 20px;
         color: #555;
         text-decoration: none;
      }
      nav#primary-nav > ul >  li {
         display: inline;
         float: left;
      }
         nav#primary-nav ul ul {
            display: none;
         }

What we have so far

Adding arrows to nav items

So we have a nice clean menu now, the next step is targeting nav items that have sub menus. We do this by checking if a parent nav item has a has-submenu class attached.

<li class="has-submenu"><a href="#">About</a>

Now we just need to write some CSS for the :after pseudo element.

nav#primary-nav li.has-submenu:after {
   position: absolute;
   right: 18px;
   top: 50%;
   transform: translateY(-50%);
   font-family: "FontAwesome"; 
   content: "\f107";
   font-size: 16px;
}

Let’s break down what we are doing here:

  • position: absolute; We are absolutely positioning the icon to the parent li.has-submenu list item.
  • right: 18px;: We are positioning the icon 18px from the right side of the parent list item.
  • top: 50%; Used in conjunction with the translateY function, we are vertically aligning the arrow in the center.
  • transform: translateY(-50%); Vertically aligns the icon.
  • font-family: “FontAwesome”; Adding the Font Awesome font to the the :after element.
  • content: “\f107”; Adding the unicode escape code for our arrow icon
  • font-size: 16px; Controls the size of our icon

Adding more padding to accommodate the icon

We’re nearly there but as you can see, the arrow is covering the text of the nav item, so we need to add some padding (double the current 20px padding) to the right hand side of the link to show the arrow.

nav#primary-nav li.has-submenu a {
   padding-right: 40px;
}

One last thing

One final thing we have to do is make the link higher up in the stack. As it currently stands, if you hover over the actual icon, the cursor doesn’t acknowledge the link and if you click it, nothing happens.

nav#primary-nav li.has-submenu a {
   padding-right: 40px;
   position: relative;
   z-index: 1;
}

Now we have a more usable navigation menu that works a treat.

The complete CSS

* { 
   margin: 0;   
   padding: 0; 
   box-sizing: border-box;
   font-family: sans-serif; 
}
nav#primary-nav {
   border: 1px solid #ccc;
   width: 100%;
   float: left;
}
   nav#primary-nav li {
      list-style: none;
      position: relative;
      border-right: 1px solid #ccc;
   }
   nav#primary-nav li.has-submenu a {
      padding-right: 40px;
      position: relative;
      z-index: 1;
   }
   nav#primary-nav li.has-submenu:after {
      position: absolute;
      right: 18px;
      top: 50%;
      transform: translateY(-50%);
      font-family: "FontAwesome"; 
      content: "\f107";
      font-size: 16px;
   }
      nav#primary-nav a {
         display: block;
         padding: 20px;
         color: #555;
         text-decoration: none;
      }
      nav#primary-nav > ul >  li {
         display: inline;
         float: left;
      }
      nav#primary-nav ul ul {
         display: none;
      }

You can reply to this post by tweeting to me