Use Superfish to Create A.D.A. Compliant Drop Down Menus in WordPress

Be aware that this tutorial requires WordPress 3.6 or above to work correctly. If you are using an older version of WordPress, you will run into issues because of the older version of hoverIntent. Please follow these instructions to ensure Superfish works correctly with WordPress 3.5.2 and below.

Typically, only the parent links of a drop down menu are selected when a user “tabs through” a horizontal navigation. However, in order to maintain 508 compliance a user must be able to tab through the drop down menus as well.

I have found the fastest and easiest way to ensure that my drop down menus are A.D.A. compliant is by using the jQuery plugin Superfish. Superfish not only allows you to tab through your drop downs, but is fantastic with touch screens, utilizes hoverIntent for a better mousing experience and automatically generates CSS arrows to show your users that there are drop down links.

It’s also compatible with older versions of Internet Explorer.

Step 1 – Include the jQuery Libraries

Superfish requires three includes to work properly: jQuery, hoverIntent, and Superfish. jQuery and hoverIntent are already packaged in WordPress so we do not need to download these libraries. You will need to download Superfish. Once you have downloaded Superfish, copy the superfish.min.js file to your WordPress theme folder.

Now that superfish.min.js is in your theme folder we can begin to set up our include. Add the code snippet below to your functions.php file. Please note that your include might look different based on the location of the superfish.min.js file:

//Inject Theme Dependent jQuery plugins
function superfish_menus() {
   // register your script location, dependencies and version

      get_template_directory_uri() . '/library/js/superfish.min.js',
      array('jquery', 'hoverIntent'),
      '1.7.4' );

   // enqueue the script

add_action('wp_enqueue_scripts', 'superfish_menus');

Now, all the jQuery libraries are included to support Superfish, but we still need to fire the script.  Create a new .js file in your theme named superfish-init.js in the same folder as the superfish.min.js file. You will probably have to modify the snippet below to correctly target the container including your navigation. Copy and paste in the following code snippet to get started:

(function($) {
	$("#parent-navigation .menu > ul").superfish({
		delay:       1, // one second delay on mouseout
		speed:       1	// faster animation speed

Be aware that are a ton of options for Superfish. The snippet above is very simple, but does the job. You can always add more options if your site requires them.

Now, let’s amend the superfish-init.js include to the superfish.min.js include. The final code snippet for your functions.php file should look something like this:

//Inject Theme Dependent jQuery plugins
function superfish_menus() {
   // register your script location, dependencies and version

      get_template_directory_uri() . '/library/js/superfish.min.js',
      array('jquery', 'hoverIntent'),
      '1.7.4' );

      get_template_directory_uri() . '/library/js/superfish-init.js',
      array('jquery', 'hoverIntent'),

   // enqueue the script

add_action('wp_enqueue_scripts', 'superfish_menus');

All the jQuery includes are ready to go!

Step 2 – Modify the CSS

The CSS must be modified for Superfish to work at it’s full potential. However, everyone’s drop down CSS code is going to be different. I’m including what I typically use to start styling my drop down menus:

#parent-navigation {
    position: absolute;
    top: 172px;
    clear: both;
    display: block;
    float: left;
    margin: 0 auto 6px 10px;
#parent-navigation ul {
    font-size: 13px;
    list-style: none;
    margin: 0 0 0 -0.8125em;
    padding-left: 0;
#parent-navigation li {
    float: left;
    position: relative;
#parent-navigation a {
    color: #eee;
    display: block;
    line-height: 2.7em;
    padding: 0 1.4em;
    text-decoration: none;
#parent-navigation ul li { border-left: 1px solid #2f3335 }
#parent-navigation ul ul {
    -moz-box-shadow: 0 3px 3px rgba(0,0,0,0.2);
    -webkit-box-shadow: 0 3px 3px rgba(0,0,0,0.2);
    box-shadow: 0 3px 3px rgba(0,0,0,0.2);
    display: none;
    float: left;
    margin: 0;
    position: absolute;
    top: 2.7em;
    left: 0;
    width: 196px;
    z-index: 99999;
#parent-navigation ul ul li { border-left: none }
#parent-navigation ul ul ul {
    left: 100%;
    top: 0;
#parent-navigation ul ul a {
    background: #f9f9f9;
    border-left: none !important;
    border-bottom: 1px solid #e8e8e8;
    color: #444;
    font-size: 13px;
    font-weight: normal;
    height: auto;
    line-height: 1.4em;
    padding: 10px 10px 10px 18px;
    width: 168px;
#parent-navigation li:hover > a,
#parent-navigation ul ul:hover > a,
#parent-navigations li.sfHover,
#parent-navigation ul ul .sfHover,
#parent-navigation a:focus {
    color: #404446;
    background: #fbfbfb;
#parent-navigations li:hover > a,
#parent-navigation a:focus {
    background: #f9f9f9; /* Show a solid color for older browsers */
    background: -moz-linear-gradient(#f9f9f9, #e5e5e5);
    background: -o-linear-gradient(#f9f9f9, #e5e5e5);
    background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f9f9f9), to(#e5e5e5)); /* Older webkit syntax */
    background: -webkit-linear-gradient(#f9f9f9, #e5e5e5);
    color: #373737;
#parent-navigation ul li:hover > ul,
#parent-navigation ul li.sfHover > ul { display: block }
#parent-navigation .current-menu-item > a,
#parent-navigation .current-menu-ancestor > a,
#parent-navigation .current_page_item > a,
#parent-navigation .current_page_ancestor > a { font-weight: bold }
/*** arrows (for all except IE7) **/
.sf-arrows .sf-with-ul {
    padding-right: 2.5em;
    *padding-right: 1em; /* no CSS arrows for IE7 (lack pseudo-elements) */
/* styling for both css and generated arrows */
.sf-arrows .sf-with-ul:after {
    content: '';
    position: absolute;
    top: 50%;
    right: .4em;
    margin-top: -3px;
    height: 0;
    width: 0;
    /* order of following 3 rules important for fallbacks to work */
    border: 4px solid transparent;
    border-top-color: #eee; /* edit this to suit design (no rgba in IE8) */
.sf-arrows > li > .sf-with-ul:focus:after,
.sf-arrows > li:hover > .sf-with-ul:after,
.sf-arrows > .sfHover > .sf-with-ul:after {
    border-top-color: #3c3f41; /* IE8 fallback colour */
/* styling for right-facing arrows */
.sf-arrows ul .sf-with-ul:after {
    margin-top: -5px;
    margin-right: -3px;
    border-color: transparent;
    border-left-color: #3c3f41; /* edit this to suit design (no rgba in IE8) */
.sf-arrows > ul li > .sf-with-ul:focus:after,
.sf-arrows > ul li:hover > .sf-with-ul:after,
.sf-arrows > ul .sfHover > .sf-with-ul:after { border-top-color: #3c3f41 }

Now, like I was saying, your CSS is different. However, please pay close attention to any lines that reference the .sfHover class. Notice that I added them in to any lines that contained the pseudo class :hover.

Chances are you are using :hover to trigger your drop downs, so this shouldn’t be too hard to mimic in your own CSS. The basic pattern is:

/*If you see a line like the one below*/
#parent-navigation li:hover > a {}
/*Add in another line so it looks like*/
#parent-navigation li:hover > a,
#parent-navigations li.sfHover {}

That’s it! You should now be able to tab through your drop down menu with the added benefit of having hoverIntent and automatically generated drop down arrows for a better user experience.

Leave a Reply

Your email address will not be published. Required fields are marked *