Create Twitter-Style Dropdowns Using MooTools

By on  
Twitter Dropdown

Twitter does some great stuff with JavaScript. What I really appreciate about what they do is that there aren't any epic JS functionalities -- they're all simple touches. One of those simple touches is the "Login" dropdown on their homepage. I've taken some time to duplicate that functionality with MooTools.


<div id="menu1"><div class="relative">
	<a href="/demos" title="Popular MooTools Tutorials" id="dd1" class="dropdown" style="width:170px;text-decoration:none;"><span>Menu 1</span></a>
	<div id="dropdown1" class="dropdown-menu">
		<a href="/about-david-walsh" title="Learn a bit about me.">About Me</a>
		<a href="/page/1" title="The David Walsh Blog">Blog</a>
		<a href="/chat" title="#davidwalshblog IRC Chat">Chat</a>
		<a href="/contact" title="Contact David Walsh">Contact Me</a>
		<a href="/demos" title="CSS, PHP, jQuery, MooTools Demos">Demos &amp; Downloads</a>
		<a href="/js" title="ScrollSpy, Lazyload, Overlay, Context Menu">MooTools Plugins</a>
		<a href="/network" title="David Walsh Blog, Script &amp; Style, Band Website Template, Wynq">Network</a>
		<a href="/web-development-tools" title="JS, CSS Compression">Web Dev Tools</a>

<div id="menu2"><div class="relative">
	<a href="/demos" title="Popular MooTools Tutorials" id="dd2" class="dropdown" rel="dropdown2" style="width:170px;text-decoration:none;"><span>Menu 2</span></a>
	<div id="dropdown2" class="dropdown-menu">
		<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>

A series of DIVS wrapping a link (the dropdown "trigger") and a DIV containing the menu items.


/* dropdowns: general */
a.dropdown { background: #88bbd4; padding: 4px 6px 6px; text-decoration: none; font-weight: bold; color: #fff; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; }
a.dropdown:hover { background: #59b; }
a.dropdown { position: relative; margin-left: 3px; }
a.dropdown span { background-image: url(toggle_down_light.png); background-repeat: no-repeat; background-position: 100% 50%; padding: 4px 16px 6px 0; }
a.dropdown.dropdown-active { color:#59b; background-color:#ddeef6; }
a.dropdown.dropdown-active span { background:url(toggle_up_dark.png) 100% 50% no-repeat; }
.dropdown-menu	{ background:#ddeef6; padding:7px 12px; position:absolute; top:16px; right:0; display:none; z-index:5000; -moz-border-radius-topleft: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-top-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; }
	.dropdown-menu p { font-size:11px; }
.dropdown-menu a:link, .dropdown-menu a:visited	{ font-weight:bold; color:#59b; text-decoration:none; line-height:1.7em; }
.dropdown-menu a:active, .dropdown-menu a:hover { color:#555; }

/* dropdowns: specific */
#menu1			{ float:left; margin-right:20px; }
	#dropdown1	{ width:150px; }
	#dropdown1 a	{ display:block; }
#menu2			{ float:left; }
	#dropdown2	{ width:150px; font-size:11px; }
.relative		{ position:relative; }

There's a lot of CSS involved but most of it is simple visual styling as opposed to styling for JavaScript's sake. Do, however, note where relative and absolute positioning is used. The outermost DIV may be positioned absolutely if you'd like. Also note that I'm not doing anything to accommodate for rounded corners in IE -- I recommend DD_Roundies for that.

The MooTools JavaScript

window.addEvent('domready',function() {
	(function($) {
		/* for keeping track of what's "open" */
		var activeClass = 'dropdown-active', showingDropdown, showingMenu, showingParent;
		/* hides the current menu */
		var hideMenu = function() {
			if(showingDropdown) {
		/* recurse through dropdown menus */
		$$('.dropdown').each(function(dropdown) {
			/* track elements: menu, parent */
			var menu = dropdown.getNext('div.dropdown-menu'), parent = dropdown.getParent('div');
			/* function that shows THIS menu */
			var showMenu = function() {
				showingDropdown = dropdown.addClass('dropdown-active');
				showingMenu = menu.setStyle('display','block');
				showingParent = parent;
			/* function to show menu when clicked */
			dropdown.addEvent('click',function(e) {
				if(e) e.stop();
			/* function to show menu when someone tabs to the box */
			dropdown.addEvent('focus',function() {
		/* hide when clicked outside */
		$(document.body).addEvent('click',function(e) {
			if(showingParent && !e.target || !$(e.target).getParents().contains(showingParent)) { 

I've commented to the code to illustrate what each block does. In a nutshell:

  • I create placeholder variables which will keep track of the current menu, dropdown, and parent for the opened menu. This functionality is only included because I don't want more than one menu to be open at a time.
  • I create a function that hides the current menu -- this can be used from anywhere within the closure.
  • I cycle through each dropdown and add events to relevant elements to show and hide menus.
  • I add an event to the body to close the current menu if the user clicks outside of the menu.

That's it!

Look forward to a MooTools Class version soon. Also look forward to jQuery and Dojo versions!

Track.js Error Reporting

Recent Features

  • CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

  • 5 More HTML5 APIs You Didnât Know Existed

    The HTML5 revolution has provided us some awesome JavaScript and HTML APIs.  Some are APIs we knew we've needed for years, others are cutting edge mobile and desktop helpers.  Regardless of API strength or purpose, anything to help us better do our job is a...

Incredible Demos

  • Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API,...

  • Sexy Opacity Animation with MooTools or jQuery

    A big part of the sexiness that is Apple software is Apple's use of opacity. Like seemingly every other Apple user interface technique, it needs to be ported to the web (</fanboy>). I've put together an example of a sexy opacity animation technique...


  1. Simple, yet effective. I also really like the Twitter login form… takes no space from the UI, and have everything a forms would need…

    Thanks for the tut.

  2. Ahmed

    How about an option to manipulate where the sub-menu will appear, top or bottom?

  3. This is great. I was just recently wondering how to make a menu close if someone clicks off of it.


  4. Nick

    Though the dropdown should also close when clicking on the Menu1 ‘button’, as indicated by the arrow change. (Firefox 3.6)

  5. @Nick: Ah yes, I shall update the arrows.

  6. I have a problem with the menu pull down going off screen. I have monitor setup as 900×1440. I don’t have any way to scroll the screen over to even read any of the menu. It works fine if I use monitor in 1440×900 mode and I like the concept.

    Shouldn’t there be a way for the browser to know that you’ve pasted something into the DOM that is now potentially off screen?

    I wouldn’t use this because the usability hit for folks.

  7. would love to see a jquery version eventually =)

  8. Your implementation is nice – but I have to say I *hate* that feature of twitter.

    For some reason their “remember me” setting doesn’t work, so every time I go to the site I have to log in. They compound the problem by adding an extra click on the page in order to access the login. I actually wrote a greasemonkey script to undo it (you can also go to twitter.com/login and get the same affect – but for some reason it didn’t occur to me check for that before I wrote it)

  9. Elizalde P. Castillo

    @Ryan Rampersad: i have a thesis project and were using php and mysql programming language. actually i have little bit background for this software and its hard to build transaction system with this bec im just only a beginner.. i want to explore more using php and please help me with my problem? and wanting also to learn mootools later on. i just want to learn those pop-up messages and icon, those amazing effects. i hope you consider me to help. thank you and God Bless!

  10. Nice one david…
    Liked the trick the hide menu
    “showingParent && !e.target || !$(e.target).getParents().contains(showingParent)”

    Will definitely use it in some of my project

  11. One more thing. It would have been better if the menu could adjust to right or left depending upon the screen size.

    On lower screen resolution Menu 1 goes off the screen.

  12. @Nitin, @Dwight Blubaugh: Can you provide a screenshot?

  13. @David Walsh: Emailed it to you.

  14. @David Walsh: I’d like to see how we can get the menus to go back up when they are clicked again. I tried to use dropdown.toggle(); but the event would cause the page to go to /demo.


  15. Seems I got it working, probably not the best way to go about it. Created a global variable called ‘tmp’ and had it initialized to false.

    /* function to show menu when clicked */
    dropdown.addEvent('click', function(e) {
    	if(e) e.stop();
    	if(tmp == false){
    		tmp = true;	
    		tmp = false;

    This does the trick though; menus are collapsible now. To keep it all in sync, this needs to be added too:

    /* hide when clicked outside */
    $(document.body).addEvent('click',function(e) {
    	if(showingParent && !e.target || !$(e.target).getParents().contains(showingParent)) { 
    		tmp = false;
    • Your solution works great as long as there is only 1 single dropdown involved. In my case I need to display 3 dropdowns.

      That happens: I open menu1 with a click. When clicking on menu2, menu 1 closes. I have to click menu2 again to open it. It is absolutely logical, but sadly not the behavior I was looking for ^^

      Any other ideas?

    • Alright, here is the solution: http://jsfiddle.net/PkbeZ/

      With a little help from wowenkho (http://www.mooforum.net/member/wowenkho/).

  16. m4co

    How would you do this with ‘mouseover’ instead of click?

    Mouseover seems complicated.. when the user goes to the child the list will just disappear! obviously because the you just left the ‘mouseover’ area

  17. I know that one year has passed since this guide has been posted, but I will use this drop down technique on the next update of my website.

    This drop down still works fantastic with mootools 1.3.

    Thank you for sharing this! You made my day :)

  18. bobthebob

    Again, a great tut from David. what a nice resource website it is!

    I would also like to see a mouseover event. When changing from click to mouceover or mouseenter, it works to open the menu.
    But i can not manage to have it close on mouseout.

    any idea?

  19. SkyGuy

    I tried copying all the code to make sure everything worked, so that after I can implement it in my own style, But for some reason mine won’t close when you click outside the menu. Although If I add a div like around the menu, then I can close the menu by clicking inside that div, but not by clicking anywhere on the body. Do you have any idea why that is?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OSCON Portland:  Conference  Discount!

    O'Reilly puts on the best web industry conferences in the world.  These conferences include Fluent Conference, Velocity Conference, and the upcoming OSCON in Portland, Oregon from July 20-24.  Open Source Convention (OSCON) is a conference that focuses specifically on open source developers and the tools and possibilities...

  • Follow Redirects with cURL

    I love playing around with cURL. There's something about loading websites via command line that makes me feel like some type of smug hacker, just like tweeting from command line does. I recently cURL'd the Google homepage and saw the following: I found it weird that Google...

  • Developers Have WordPress, Amateurs Have Squarespace, Professional Designers Have the NEW Webydo!

    Web design platforms have traditionally come in one of two varieties. There are the solutions like WordPress and Drupal that are incredibly powerful, but an understanding of web development and coding is required to be able to use those platforms effectively. On the other side of the...

  • Chris Coyierâs Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it’s damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

  • GSAP + SVG For Power Users: Motion Along A Path

    Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock’s own Forum and Documentation. This article isn’t intended for beginners, but rather a...