HoverIntent in WordPress

Whenever you’re working on a new WordPress theme that includes hover (mouseover) effects, especially dropdown or flyout menus, you might want to include hoverIntent. HoverIntent is a term that describes a concept through which you delay a hover action until a certain amount of time has passed, in order to make sure that the user really intended to trigger that action.

We’ve all been on websites with dropdown menus that tend to get in the way of the content, and pop open as soon as your mouse touches even a small portion of them, and we’ve most likely all been annoyed by it. The idea behind hoverIntent is to measure the speed of the mouse movement, attempting to determine whether the user actually intended to stop on the item or not. If the mouse just moves over an item with a hover effect, but doesn’t stop on it, the hover effect should not be triggered; if, however, the user’s mouse does slow down enough or stop on the item, the hover effect should be triggered.

Back in 2007, Brian Cherne submitted the first version of a jQuery plugin attempting to fix this issue. The plugin was called hoverIntent, and has become somewhat synonymous with the usability concept discussed above.

The WordPress gang was actually fairly quick to pick up on this, and began including Brian’s hoverIntent plugin in the WordPress core when WordPress 2.7 was released. That’s right, hoverIntent has been part of the WordPress core since December 2008.

However, until version 3.3 of WordPress, the hoverIntent script was only registered in WordPress from within the admin area; it wasn’t readily available (without using wp_register_script() to register it yourself) on the front-end. As of version 3.3, though, the registration of hoverIntent was moved outside of the admin area so that it is easily available throughout a WordPress site, on the front-end and back-end.

To use hoverIntent, you simply need to enqueue it by using wp_enqueue_script( 'hoverIntent' ) or even by including the handle ‘hoverIntent’ in the list of dependencies when registering your own script file in your theme or plugin.

Then, if you want to actually apply hoverIntent to an element in your theme or plugin, you simply need to call it from within your JavaScript. To use hoverIntent, you simply call:

jQuery( [selector] ).hoverIntent( [over-callback], [timeout], [out-callback] )

Normally, for accessibility purposes, you should use hoverIntent as an enhancement for normal hover effects, ensuring that the hover effect doesn’t stop working altogether if JavaScript fails. Therefore, you probably want to include a default hover effect that occurs without JavaScript, then add a delay to that effect with the hoverIntent method.

To do that, though, you’ll need to use some JavaScript to determine whether or not JavaScript is active on the page. Usually, you do this by adding a CSS class to the body element that then gets removed by JavaScript.

For instance, the initial HTML for your body element might look like:

<body class="no-js">

Then, within your JavaScript file (assuming you have jQuery enabled, which is required in order to use hoverIntent), you would add a line that looks something like:

jQuery( function( $ ) { $( 'body' ).removeClass( 'no-js' ); } );

Then, your CSS would look something like:

a:focus, .no-js a:hover, a.hover { text-decoration: underline; }

and your call to hoverIntent would look like:

 $( 'a' ).hoverIntent( function() { $( this ).addClass( 'hover' ); }, 100, function() { $( this ).removeClass( 'hover' ); } ); 

Now, normally you wouldn’t use hoverIntent to simply add or remove an underline from a link; but the concept remains the same no matter what hover effect you’re applying.

2 Responses

  • Tim Cooper

    Thanks for this.
    I found that, for me, hoverIntent wasn’t working until i was logged in. Enqueing it myself solved the problem!

    • Hey Tim, thanks for sharing this.
      This probably has to do with recent versions of WordPress as this article was written with WordPress 3.3 in mind

Post Your Comment

Your email address will not be published.