Note: there is now an official GitHub repository for Superfish.
Overview
Superfish is an enhanced Suckerfish-style menu jQuery plugin that takes an existing pure CSS drop-down menu (so it degrades gracefully without JavaScript) and adds the following much-sought-after enhancements:
- Supports touch devices. On Android, iOS, Windows Phone 7 and IE10 (with touchscreen), first touch will open an associated submenu, second will follow the link. Mouse and keyboard accessibility works as normal. Note that you currently need to include Brian Cherne’s hoverIntent plugin to support certain Android browsers' and IE10's touch interaction. This may change.
Optionally require click to open and close submenus. Added in version 1.5.2, perfected in 1.5.4.Removed in v1.7. See issue 47 for details.- Timed delay on mouseout to be more forgiving of mouse-piloting errors. Default is 800 milliseconds but can be changed via the options object
- Animations when showing submenus (and when hiding them, as of version 1.5.2). uses a fade by default but can be given custom objects to be used by the animate functions. The animation speed is also customisable.
- Keyboard accessibility. Tab through the links and the relevant submenus are revealed and hidden as needed
- Supports the hoverIntent plugin. Superfish automatically detects the presence of Brian Cherne’s hoverIntent plugin and uses its advanced hover behaviour for the mouseovers (mouseout delays are handled by Superfish regardless of the presence of hoverIntent). Using this is only an option, but a nice one. The examples on this page are using hoverIntent. If for some reason you want to use hoverIntent on your page for other plugins but do not want Superfish to use it you can set the option
disableHItotrue. Important note: As of v1.5.1 you must use the updated version (r7) of hoverIntent which supports event delegation. - Indicates the presence of submenus by adding CSS-based arrows to relevant anchors. You can turn off the arrows via the “cssArrows” option, if required.
- Can show the path to your current page while the menu is idle. The easiest way to understand this is to view the nav-bar example. Note that you need to add 'current' (or similar) classes to the relevant list item elements yourself, ideally server-side.
- Optional callback functions. These callbacks allow for further enhancements and functionality to be added without needing to alter the core Superfish code.
- Provides public methods
hideandshowthat you can call on list items that have submenu children. Also provides adestroymethod for uninitialising Superfish. Here is an example page demonstrating the methods in action - Uses event delegation as of v1.5.1 for greater performance and flexibility.
Quick Start Guide
-
Begin with a working pure CSS dropdown menu just like you would if creating a Suckerfish menu. For each li:hover selector, add an equivalent li.sfHover selector. Use
display:nonerather thanleft:-9999emto hide submenus. To make this step easy, there are cross-browser CSS files for a variety of menu types available in the download section of this site.<link href="superfish.css" rel="stylesheet" media="screen"> -
Link to the superfish.js file (after including jQuery) using a script tag in the head of your document.
<script src="jQuery.js"></script> <script src="superfish.js"></script> -
Call superfish() on the containing ul element.
There are many options available to customise your menu. You can find out about them in the Options tab of this site.<script> jQuery(document).ready(function() { jQuery('ul.sf-menu').superfish(); }); </script>
Options
Superfish’s default options:
$.fn.superfish.defaults = {
hoverClass: 'sfHover', // the class applied to hovered list items
pathClass: 'overideThisToUse', // the class you have applied to list items that lead to the current page
pathLevels: 1, // the number of levels of submenus that remain open or are restored using pathClass
delay: 800, // the delay in milliseconds that the mouse can remain outside a submenu without it closing
animation: {opacity:'show'}, // an object equivalent to first parameter of jQuery’s .animate() method. Used to animate the submenu open
animationOut: {opacity:'hide'}, // an object equivalent to first parameter of jQuery’s .animate() method Used to animate the submenu closed
speed: 'normal', // speed of the opening animation. Equivalent to second parameter of jQuery’s .animate() method
speedOut: 'fast', // speed of the closing animation. Equivalent to second parameter of jQuery’s .animate() method
cssArrows: true, // set to false if you want to remove the CSS-based arrow triangles
disableHI: false, // set to true to disable hoverIntent detection
onInit: $.noop, // callback function fires once Superfish is initialised – 'this' is the containing ul
onBeforeShow: $.noop, // callback function fires just before reveal animation begins – 'this' is the ul about to open
onShow: $.noop, // callback function fires once reveal animation completed – 'this' is the opened ul
onBeforeHide: $.noop, // callback function fires just before closing animation – 'this' is the ul about to close
onHide: $.noop, // callback function fires after a submenu has closed – 'this' is the ul that just closed
onIdle: $.noop, // callback function fires when the 'current' submenu is restored (if using pathClass functionality)
onDestroy: $.noop // callback function fires after the 'destroy' method is called on the menu container
};
You can override any of these options by passing an object into the Superfish method upon initialisation. For example:
//link to the CSS files for this menu type
<link rel="stylesheet" media="screen" href="superfish.css">
// link to the JavaScript files (hoverIntent is optional)
// if you use hoverIntent, use the updated r7 version (see FAQ)
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
// initialise Superfish
<script>
jQuery(document).ready(function() {
jQuery('ul.sf-menu').superfish({
delay: 1000, // one second delay on mouseout
animation: {opacity:'show',height:'show'}, // fade-in and slide-down animation
speed: 'fast', // faster animation speed
autoArrows: false // disable generation of arrow mark-up
});
});
</script>
Examples
The result:
The code:
The simplest use, and a good starting point for new users:
//link to the CSS files for this menu type
<link rel="stylesheet" media="screen" href="superfish.css">
// link to the JavaScript files (hoverIntent is optional)
// if you use hoverIntent, use the updated r7 version (see FAQ)
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
// initialise Superfish
<script>
jQuery(document).ready(function(){
jQuery('ul.sf-menu').superfish();
});
</script> The result:
The code:
To create an all-vertical menu, simply add the class sf-vertical to the parent ul along with the usual sf-menu class (space-separated, eg. class="sf-menu sf-vertical"), and initialise as normal. For this example I will also demonstrate altering some of the options in order to create a slide-down animation and a longer delay on mouseout:
//link to the CSS files for this menu type
<link rel="stylesheet" media="screen" href="superfish.css">
<link rel="stylesheet" media="screen" href="superfish-vertical.css">
// link to the JavaScript files (hoverIntent is optional)
// if you use hoverIntent, use the updated r7 version (see FAQ)
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
// initialise Superfish
<script>
jQuery(document).ready(function(){
jQuery('ul.sf-menu').superfish({
animation: {height:'show'}, // slide-down effect without fade-in
delay: 1200 // 1.2 second delay on mouseout
});
});
</script> The result:
Notice that if you disable JavaScript this menu degrades very nicely – as do all the other examples.
The code:
To create a horizontal nav-bar with a horizontal second tier and optional vertical third tier, simply include the superfish-navbar.css file after the main superfish.css file and add the class sf-navbar to the parent ul along with the usual sf-menu class (space-separated, eg. class="sf-menu sf-navbar"), and initialise as normal.
A nice option to add to this types of menu is restoring the relevant submenu when the user is not exploring other submenus. This can be done by telling Superfish the name of the class you are adding to the relevant <li> elements to indicate the path to the current page. I often have the server add the class name 'current' for this purpose, so I would initialise this menu thusly:
//link to the CSS files for this menu type
<link rel="stylesheet" media="screen" href="superfish.css">
<link rel="stylesheet" media="screen" href="superfish-navbar.css">
// link to the JavaScript files (hoverIntent is optional)
// if you use hoverIntent, use the updated r7 version (see FAQ)
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
// initialise Superfish
<script>
jQuery(document).ready(function(){
jQuery('ul.sf-menu').superfish({
pathClass: 'current'
});
});
</script> The result:
The code:
Important note: Unless you really need the submenus to have a max-width, this plugin is no longer needed. The CSS that comes with v1.6.0+ includes a couple of lines that emulate this behaviour. Otherwise, read on.
This menu uses the optional Supersubs plugin (currently beta) to make the submenu widths variable. The fixed width set in the CSS is overridden and all menu items within a submenu are altered to match the width of their widest sibling. This is most commonly used to make all menu items fit on one line so that they are all of equal height.
Note that Supersubs needs to be called before Superfish in the initialisation chain, as shown below:
//link to the CSS files for this menu type
<link rel="stylesheet" media="screen" href="superfish.css">
// link to the JavaScript files (hoverIntent is optional)
// if you use hoverIntent, use the updated r7 version (see FAQ)
<script src="hoverIntent.js"></script>
<script src="superfish.js"></script>
<script src="supersubs.js"></script>
// initialise Superfish
<script>
jQuery(document).ready(function(){
jQuery('ul.sf-menu').supersubs({
minWidth: 12, // minimum width of submenus in em units
maxWidth: 27, // maximum width of submenus in em units
extraWidth: 1 // extra width can ensure lines don't sometimes turn over
// due to slight rounding differences and font-family
}).superfish(); // call supersubs first, then superfish, so that subs are
// not display:none when measuring. Call before initialising
// containing tabs for same reason.
});
</script> Frequently Asked Questions
- Which versions of jQuery is the Superfish plugin compatible with?
- The Superfish plugin is compatible with jQuery v1.7 and later. It also works with jQuery v1.9.0+ as of Superfish v1.5.0 and I strongly recommend you use it.
- Does the Superfish plugin have any dependencies on other plugins?
- Nope.
- What about touch device support?
- Superfish has robust support for all Android browsers, iOS browsers and IE10 on touch devices. Be aware that you need to include hoverIntent to support IE10 and certain Android browsers (although this may change).
- Does the Superfish plugin work with any other plugins?
- Yes – here are a few useful plugins that you may wish to add to your menu:
- HoverIntent. The nicest thing you can do for your menu is include Brian Cherne’s hoverIntent plugin in your page and Superfish will automatically use it to make the user interaction more pleasing. Important note: As of v1.5.1 you must use the newly updated r7 version of hoverIntent which supports event delegation.
- Supersubs. If you want the submenu widths to change to suit their contents, simply start with the CSS that comes with v1.6.0 or up. Or, you can add the Supersubs plugin as shown in the example of the same name on this site.
- How can I make the menu look better?
- The demo style is very basic by design – you should use it as a base to build upon and skin it to suit your project. I strongly recommend testing in the earliest version of Internet Explorer you dare support in addition to modern browsers at every step of the way so that when IE bugs occur you can tell which CSS rules trigger them and work around them before moving on.
- What if something goes wrong?
- Please do not use GitHub issues to get help with your menu implementation. The cause of 99.9% of all Superfish problems are basic CSS issues. Disable JavaScript and concentrate on getting the menu working in pure CSS. If you are not a CSS expert then I advise that you follow the method described in the previous question’s answer, ie. begin with the demo CSS file and make small incremental changes, checking in a variety of browsers at every step.
- In Internet Explorer the submenus appear underneath main content div. Why? How do I solve it?
- This very common issue is thanks to the IE Z-index Bug and the solution does not involve adjusting any of the Superfish code, but rather, you need to apply certain CSS to some of your main site structure elements (usually the header div and the main content div). Please follow this link to an article that clearly explains the IE z-index bug fix for Superfish.
- What if I still need help?
- If you need help with the jQuery/JavaScript aspect of the plugin, post a message to the jQuery Forum with the word “Superfish” somewhere in the subject line. There are many Superfish users on the forum who may be able to help you.
- If your issues are related to styling and CSS, then you will need to post your questions to a purely CSS related group instead. CSS for Superfish is mainly just regular Suckerfish-style dropdown menu code so there are plenty of resources out there to learn from.
- Can I count on Superfish being supported into the future?
- Yes, it’s here for the long haul – or at least as long as it’s relevant. I will also be adding further features in the form of modular optional add-on plugins.
- Have you made any other plugins?
- Why yes, I’m thrilled that you asked. Check out my WordPress plugin “NoFollowr” for making judicious application of nofollow attributes a breeze. It is also powered by the mighty jQuery.
Download
The canonical version of Superfish lives on GitHub. Here is a shortcut to the zip archive of everything you need.
The zip archive contains the following files:
- changelog.txt
- example.html containing examples of using the available public methods 'show', 'hide' and 'destroy'.
- superfish.css
- superfish-vertical.css
- superfish-navbar.css
- jquery-1.9.1.min.js, but you should look for and use the latest version of jQuery.
- superfish.js
- supersubs.js
- hoverIntent.js – by Brian Cherne, recently updated (r7) to support event delegation
Support
Demonstrable bugs with the JavaScript component of the Superfish plugin can be reported via GitHub. However, most issues you encounter will likely relate to the CSS of your particular menu. These issues are best discussed on a dedicated CSS forum, Stack Exchange, jQuery forum, etc.