Home
Home
bigbackground

Make your long dropdown menu scrollable

The problem with long dropdowns is that the dropdown itself can go below the “fold” of the website. That is, below the visible area of the browser window. So in order to access those menu items down below, you need to scroll your browser window. Those lower menu items are totally inaccessible, because to use the browser scrollbar means mousing off the menu (and probably having it close).

View the demo with a (possible) solution here: http://www.dotflow.nl/demo/long-dropdown.html

jQuery makes it tick

First download the latest version of jQuery or put this in your header:

<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script>
  1. Set a maximum height to the dropdowns
  2. On hover, reveal the submenu
  3. Calculate a speed multiplier based on the height of the submenu
  4. Watch for mouse movement in the menu
  5. Scroll the menu with the mouse movement, based on the multiplier
  6. On mouse out, close the menu

Now add this javascript to your website and link it to your file (I called it: jquery.dropdown.js)

Javascript

var maxHeight = 400;

$(function(){

    $(".dropdown > li").hover(function() {

         var $container = $(this),
             $list = $container.find("ul"),
             $anchor = $container.find("a"),
             height = $list.height() * 1.1,       // make sure there is enough room at the bottom
             multiplier = height / maxHeight;     // needs to move faster if list is taller

        // need to save height here so it can revert on mouseout
        $container.data("origHeight", $container.height());

        // so it can retain it's rollover color all the while the dropdown is open
        $anchor.addClass("hover");

        // make sure dropdown appears directly below parent list item
        $list
            .show()
            .css({
                paddingTop: $container.data("origHeight")
            });

        // don't do any animation if list shorter than max
        if (multiplier > 1) {
            $container
                .css({
                    height: maxHeight,
                    overflow: "hidden"
                })
                .mousemove(function(e) {
                    var offset = $container.offset();
                    var relativeY = ((e.pageY - offset.top) * multiplier) - ($container.data("origHeight") * multiplier);
                    if (relativeY > $container.data("origHeight")) {
                        $list.css("top", -relativeY + $container.data("origHeight"));
                    };
                });
        }

    }, function() {

        var $el = $(this);

        // put things back to normal
        $el
            .height($(this).data("origHeight"))
            .find("ul")
            .css({ top: 0 })
            .hide()
            .end()
            .find("a")
            .removeClass("hover");

    });

    // Add down arrow only to menu items with submenus
    $(".dropdown > li:has('ul')").each(function() {
        $(this).find("a:first").append("");
    });

});

HTML

<ul>
 <li><a href="#">Really Tall Menu</a>
 <ul>
 <li><a href="#">Artificial Turf</a></li>
 <li><a href="#">Benches &amp; Bleachers</a></li>

 <li><a href="#">Communication Devices</a></li>
 <li><a href="#">Dugouts</a></li>
 <li><a href="#">Fencing &amp; Windscreen</a></li>
 <li><a href="#">Floor Protectors</a></li>
 <li><a href="#">Foul Poles</a></li>

 <li><a href="#">Netting</a></li>
 <li><a href="#">Outdoor Furniture &amp; Storage</a></li>
 <li><a href="#">Outdoor Signs</a></li>
 <li><a href="#">Padding</a></li>
 <li><a href="#">Scoreboards</a></li>

 <li><a href="#">Shade Structures</a></li>
 <li><a href="#">Artificial Turf</a></li>
 <li><a href="#">Benches &amp; Bleachers</a></li>
 <li><a href="#">Communication Devices</a></li>
 <li><a href="#">Dugouts</a></li>

 <li><a href="#">Fencing &amp; Windscreen</a></li>
 <li><a href="#">Floor Protectors</a></li>
 <li><a href="#">Foul Poles</a></li>
 <li><a href="#">Netting</a></li>
 <li><a href="#">Outdoor Furniture &amp; Storage</a></li>

 <li><a href="#">Outdoor Signs</a></li>
 <li><a href="#">Padding</a></li>
 <li><a href="#">Scoreboards</a></li>
 <li><a href="#">Shade Structures</a></li>
 <li><a href="#">Artificial Turf</a></li>
 <li><a href="#">Benches &amp; Bleachers</a></li>

 <li><a href="#">Communication Devices</a></li>
 <li><a href="#">Dugouts</a></li>
 <li><a href="#">Fencing &amp; Windscreen</a></li>
 <li><a href="#">Floor Protectors</a></li>
 <li><a href="#">Foul Poles</a></li>

 <li><a href="#">Netting</a></li>
 <li><a href="#">Outdoor Furniture &amp; Storage</a></li>
 <li><a href="#">Outdoor Signs</a></li>
 <li><a href="#">Padding</a></li>
 <li><a href="#">Scoreboards</a></li>

 <li><a href="#">Shade Structures</a></li>
 </ul>
 </li>
 <li><a href="#">Kinda Tall Menu</a>
 <ul>
 <li><a href="#">Artificial Turf</a></li>
 <li><a href="#">Benches &amp; Bleachers</a></li>

 <li><a href="#">Communication Devices</a></li>
 <li><a href="#">Dugouts</a></li>
 <li><a href="#">Fencing &amp; Windscreen</a></li>
 <li><a href="#">Floor Protectors</a></li>
 <li><a href="#">Foul Poles</a></li>

 <li><a href="#">Netting</a></li>
 <li><a href="#">Outdoor Furniture &amp; Storage</a></li>
 <li><a href="#">Outdoor Signs</a></li>
 <li><a href="#">Padding</a></li>
 <li><a href="#">Scoreboards</a></li>

 </ul>
 </li>
 <li><a href="#">Average Menu</a>
 <ul>
 <li><a href="#">Artificial Turf</a></li>
 <li><a href="#">Benches &amp; Bleachers</a></li>

 <li><a href="#">Communication Devices</a></li>
 <li><a href="#">Dugouts</a></li>
 <li><a href="#">Fencing &amp; Windscreen</a></li>
 </ul>
 </li>
 <li><a href="#">No Menu</a>

 </li>
 </ul>

CSS

*{ margin: 0; padding: 0; }
body{ font: 15px Helvetica, Sans-Serif; }
html{ overflow-y: scroll; }
#container { width: 720px; margin: 25px auto; }
p{ margin: 0 0 8px 0; }
a{ text-decoration: none; }
img{ vertical-align: middle; }
a img{ border: 0; 180}
ul{ list-style: none; }
h1{ margin: 0 0 10px 0; }

/*
	LEVEL ONE
*/
ul.dropdown{ position: relative; width: 100%; }
ul.dropdown li{ font-weight: bold; float: left; width: 180px; background: #ccc; position: relative; }
ul.dropdown a:hover{ color: #000; }
ul.dropdown li a{ display: block; padding: 20px 8px; color: #222; position: relative; z-index: 2000; }
ul.dropdown li a:hover, ul.dropdown li a.hover { background: #F3D673; position: relative; }

/*
	LEVEL TWO
*/
ul.dropdown ul{ display: none; position: absolute; top: 0; left: 0; width: 180px; z-index: 1000; }
ul.dropdown ul li{ font-weight: normal; background: #f6f6f6; color: #000; border-bottom: 1px solid #ccc; }
ul.dropdown ul li a{ display: block; background: #eee !important; }
ul.dropdown ul li a:hover{ display: block; background: #F3D673 !important; }

That’s it! you can view the demo here

2 Comments »

  1. avatar comment-top

    Dude!!!
    Deze ga ik eens effe lekker gebruiken ;)
    Had hem net nodig…!

    Ga hem alleen niet in een navigatie tonen.. Ik zal je het resultaat binnenkort sturen..
    Eind van de week is die site af ;)

    groetjes!

    comment-bottom
  2. avatar comment-top

    Ja ik kwam deze tut tegen, echt heel erg rlxt!

    comment-bottom

RSS feed for comments on this post. TrackBack URL

Leave a comment