Scrollable Twitter Bootstrap Menus

Twitter Bootstrap has some pretty nice features, but one of the more common practices left out of its component stack is the ability to have long dropdown menus that scroll their content. A quick search on Google brought up some possible solutions, but a lot of them involved JavaScript/Plug-ins or directly hacked into the CSS of bootstrap. Each of which have their own advantages (JavaScript allows for more control, CSS only prevents unnecessary DOM manipulations). However, I’ve typically find myself consumed in the abyss of hacks that worked, but just so happened to brake another functionality of the framework I’m using. Sure, the hack may work in a lot of situations… but just not mine 😦 So, instead of taking another performance hit with a JS solution or using just CSS that may have some unintended consequences, I decided to use a combination of CSS and HTML to tackle the problem. The use of a few extra HTML tags along with some *hopefully* less intrusive CSS will lessen the chances that I’d screw up the intended purpose of the component I’m trying to add the feature to!

Here are a few benefits that this approach will give us:

  • No JavaScript
  • Does not interfere with the layout/CSS of the menu you’re trying to scroll content for
  • Works with multiple scroll-menu in the same dropdown-menu
  • Works with dropdown-submenu
  • Works in responsive mode and mobile/touch enabled
  • Allows for static headers and footers that will not scroll with the content using the normal list items
  • The scroll-menu will grow dynamically until it reaches the max-height (at which point it will show a vertical scrollbar for each scroll-menu)

Well, I’ll cut to the chase and give you the solution I came up with *because nothings more irritating than trying to search through all the wrong ways someone did something before you find the final solution* (or you can jump to the final JFiddle example)

CSS

/* So we wont impact the original bootstrap menu
or it's pseudo call-out arrow the menu is wrapped
in a sub dropdown-menu with a chained scroll-menu */
ul.scroll-menu {
    position: relative;
    display: inherit !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    -moz-overflow-scrolling: touch;
    -ms-overflow-scrolling: touch;
    -o-overflow-scrolling: touch;
    overflow-scrolling: touch;
    top: 0 !important;
    left: 0 !important;
    width: 100%;
    height: auto;
    max-height: 500px;
    margin: 0;
    border-left: none;
    border-right: none;
    -webkit-border-radius: 0 !important;
    -moz-border-radius: 0 !important;
    -ms-border-radius: 0 !important;
    -o-border-radius: 0 !important;
    border-radius: 0 !important;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    -ms-box-shadow: none;
    -o-box-shadow: none;
    box-shadow: none;
}

HTML

<!-- Example of a single scrollable dropdown-menu navigation 	 (notice the placement of the "scroll-menu" class) --></pre>
<ul class="nav">
	<li class="dropdown"><a href="#" data-toggle="dropdown">
 <b class="icon-th-large icon-white"></b>
 </a>
<ul class="dropdown-menu">
<ul class="dropdown-menu"><!-- static non-scrollable menu header --></ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu">
	<li class="disabled"><a href="#"><b>My Theme:</b></a></li>
	<li><!-- Here we have our dropdown-menu wrapper so we don't mess 					 with the layout of the outer dropdown-menu -->
<ul class="dropdown-menu scroll-menu">
<ul class="dropdown-menu scroll-menu">
	<li><a href="#"><i class="icon-asterisk"></i> Start</a></li>
	<li><a href="#"><i class="icon-minus"></i> UI Lightness</a></li>
</ul>
</ul>
<ul class="dropdown-menu scroll-menu"><!-- Keep adding more list items and watch how your menu 						 will grow w/o a vertical scollbar until it reaches 						 the max-height set in the scroll-menu class --></ul>
</li>
</ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu"><!-- static non-scrollable menu footer --></ul>
</ul>
<ul class="dropdown-menu">
	<li class="disabled"><a href="#">
 <i class="icon-chevron-up pull-left"></i>
 <i class="icon-chevron-up pull-right"></i>
 </a></li>
</ul>
</li>
</ul>
<pre>

Result

scroll-menu1

Now that we have a scroll-menu working that’s decoupled from our main dropdown-menu, lets try to add multiple scroll-menus to our main dropdown-menu (again, you can skip to the complete JFiddle example if you’d like):

HTML

<!-- Example of a multiple scrollable dropdown-menu navigation      (notice the placement of the "scroll-menu" class as well      as the "scroll-menu-2x" class that helps to cut the      max-height down to about 1/2 the size of our normal      scroll-menu max-height) --></pre>
<ul class="nav">
	<li class="dropdown"><a href="#" data-toggle="dropdown">
 <b class="icon-key icon-white"></b>
 </a>
<ul class="dropdown-menu">
<ul class="dropdown-menu"><!-- static non-scrollable menu header 1 --></ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu">
	<li class="disabled"><a href="#"><i class="icon-group"></i> <b>My Groups</b></a></li>
	<li>
<ul class="dropdown-menu scroll-menu scroll-menu-2x">
<ul class="dropdown-menu scroll-menu scroll-menu-2x">
	<li><a href="#">User</a></li>
	<li><a href="#">Administrators</a></li>
	<li><a href="#">Some Other Group</a></li>
</ul>
</ul>
<ul class="dropdown-menu scroll-menu scroll-menu-2x"><!-- Additional menu items omitted for brevity --></ul>
</li>
</ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu"><!-- static non-scrollable menu header 2 --></ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu">
	<li class="disabled"><a href="#"><i class="icon-user"></i> <b>My Roles</b></a></li>
	<li>
<ul class="dropdown-menu scroll-menu scroll-menu-2x">
<ul class="dropdown-menu scroll-menu scroll-menu-2x">
	<li><a href="#">Core Users</a></li>
	<li><a href="#">Admin</a></li>
	<li><a href="#">Some Other Role</a></li>
</ul>
</ul>
<ul class="dropdown-menu scroll-menu scroll-menu-2x"><!-- Additional menu items omitted for brevity --></ul>
</li>
</ul>
</ul>
<ul class="dropdown-menu">
<ul class="dropdown-menu"><!-- static non-scrollable menu footer --></ul>
</ul>
<ul class="dropdown-menu">
	<li class="disabled"><a href="#">
 <i class="icon-chevron-up pull-left"></i>
 <i class="icon-chevron-up pull-right"></i>
 </a></li>
</ul>
</li>
</ul>
<pre>

Result

scroll-menu2

…and last, but not least we have the famed dropdown-submenu. This is where a lot of other solutions either partially work or do not work at all. While the proposed hack I’m suggesting may not be perfect it seems to get us going with a minimal impact on the core bootstrap implementation. Most of the HTML below should look almost identical to the way the normal dropdown-menu / dropdown-submenu is laid out with the addition of an added “dropdown-menu scroll-menu“:

scroll-menu3

Let me know if you find a better solution or have made improvements to the original JFiddle example!

About ugate
UGate is a fully open source solution for a do-it-yourself configurable indoor/outdoor security system. It's built with Arduino Uno32 (ChipKIT) + JavaFX and a number of other leading software/hardware technologies. Our goal is to provide individuals with access to the most popular hardware sensor technology used in industrial today. Our attempt is to bridge the gap between the hardware and software in an extendable and intuitive GUI interface that is free and open to the public. Visit our code page at: http://ugate.org

13 Responses to Scrollable Twitter Bootstrap Menus

  1. David Holt says:

    This is really useful, but any menu which is made scrollable prevents the use of nested submenus within that menu. My main menu is the monster: the submenus are pretty short. Is there a simple way to force submenus to display ‘outside’ the scrollable area?

    (also the coding examples above seem to have a lot of repeated lines, so they’re pretty unhelpful)

    • ugate says:

      Bootstrap has dropped support for submenus in version 3. So, I’m not sure you’ll find much support for them going forward. Bootstrap obviously didn’t supply support for off-screen submenus. So, I think that will require some javascript on your part to get it to work the way you want them to.

      The example has a lot of repeated lines in order to illustrate a large amount of menu items within the menu. Without it, the scrollbars would not show up (as seen in the screen shot).

  2. Chris says:

    Hey, that’s a great tweak you’ve got there. Thanks a million! However, it is notable that I don’t see it working in mobile. Any ideas?

  3. Elias says:

    How I can make it work with a simple Button with drop-down? I tried to implement it, but the menu is always open. Here’s what I’m doing. http://jsfiddle.net/veJf9/

  4. Elias says:

    I forgot the link of the updated version: http://jsfiddle.net/veJf9/4/

  5. Jerryps79 says:

    You are a star! Thank you so much!!

  6. wally says:

    Good work but not wirking on mobile browsers version (i.e. Chrome Mobile). I can’t select any menu item when is scrollable.

  7. Linh says:

    Ugate, thank you so much for this! It has helped me so much. I have a similar problem to Elias, but when I put in the fix you gave him, it caused another issue. When you click on the word partner in my jsfiddle, you’ll see the submenu overlays the menu item. I tried messing with the css, but couldn’t get it right. The fiddle is here: http://jsfiddle.net/ftLLH/ and the menu item with the issue is PARTNERS. Thanks!!!

  8. bijupet says:

    The fiddle didn’t work in IE 11. Have you tested in IE? Just wondering.

Leave a comment