SpiffyJr's Blogaroo

Happenings of the man known as SpiffyJr

  • Home
  • About
    • Inspiration
    • Resume
  • Projects
    • Blitzaroo
    • phpRaider
    • Zend Calendar
  • Docs
    • Blitzaroo API
    • SpiffyCalendar Docs
    • SpiffyDb Docs
  • Downloads
  • Technologies
    • Doctrine ORM
    • Dojo
    • PHP
    • Zend Framework
  • Other
    • License
Twitter RSS

Creating fancy drop-down menus with HTML, CSS, and Dojo.

Posted on March 2, 2010 by SpiffyJr
15 commentsLeave a comment

Preface

Waaaaasssuuuuupppp? Kidding. Drop-down menus are always a pain for me because you have to remember to do all kinds of CSS and it has to work in 45 different browsers. Rubbish, I say! I recently decided to add an animated drop-down menu to Blitzaroo for the user section. The HTML/CSS was pretty straight forward but I hit a snag with the JavaScript so I sent an email to the Dojo Toolkit Mailing List and got a quick response from Peter Higgins (those Dojo guys are awesome). I promised a few blogs (and more to come in the future)  to showcase some of Dojo’s quick & easy wow features. This post assumes that you already know the basics about Dojo and have included Dojo somewhere in your project. If not, please check out Dojo Campus and the Dojo Toolkit homepage to get started.

Live Demonstration

Take a peak at the live demonstration to see where we’re headed. If you’re interested in how I got there keep on reading!

The HTML

The HTML is pretty straight forward and utilizes an unordered list for the layout. Note: all of the code here is going to be a straight copy/paste from the Blitzaroo source.

<ul id="userMenu" class="tabs">
	<li>
		<div>
			<img src="/images/icons/14/add.png" alt="Add" />
			Add <span class="downArrow">&#9660;</span>
		</div>
		<ul class="dropdown">
			<li>
				<a href="/user/events/add">
					<img src="/images/icons/14/events.png" alt="Event" />
					Event
				</a>
			</li>
			<li>
				<a href="/user/profiles/add">
					<img src="/images/icons/14/profiles.png" alt="Profile" />
					Profile
				</a>
			</li>
			<li>
				<a href="/user/teams/add">
					<img src="/images/icons/14/teams.png" alt="Team" />
					Team
				</a>
			</li>
		</ul>
	</li>
	<li>
		<a href="/user">
			<img src="/images/icons/14/dashboard.png" alt="Dashboard" />
			Dashboard
		</a>
	</li>
	<li>
		<a href="/user/events">
			<img src="/images/icons/14/events.png" alt="Events" />
			Events
		</a>
	</li>
	<li>
		<a href="/user/profiles">
			<img src="/images/icons/14/profiles.png" alt="Profiles" />
			Profiles
		</a>
	</li>
	<li>
		<a href="/user/teams">
			<img src="/images/icons/14/teams.png" alt="Teams" />
			Teams
		</a>
	</li>
</ul>

The only required attributes are class=”tabs” on the root <ul> and class=”dropdown” on each <ul> that is going to be a drop-down menu. The above menu has four regular links (Dashboard, Events, Profiles, and Teams.) and one drop-down menu (Add). I’ve spruced it up a bit by adding a few images but that is completely optional. I use the id tag on the root <ul> for styling the menu. No surprise here but the HTML renders a menu that looks like:

The CSS

.downArrow {
	font-size: 85%;
	vertical-align: text-bottom;
}

#userMenu {
	-webkit-border-radius: 8px;
	background: #f5faf5;
	border: 1px solid #bbcfbb;
	display: table;
	font-size: 13px;
	font-weight: bold;
	list-style-type: none;
	margin: 8px 0;
	padding: 0 12px;
	position: relative;
}

#userMenu li {
	cursor: pointer;
	font-size: 12px;
	list-style: none;
	display: table-cell;
	float: left;
	position: relative;
	text-shadow: 0px 0px 1px #fff;
}

#userMenu li a,#userMenu li div {
	color: #154f14;
	font-size: 11px;
	padding: 5px 12px;
}

#userMenu li a:hover,#userMenu li div:hover {
	background-color: #dae8da;
	text-decoration: none;
}

#userMenu img {
	margin-right: 3px;
	vertical-align: top;
}

#userMenu a {
	position: relative;
	display: block;
}

#userMenu .dropdown {
	-webkit-border-bottom-left-radius: 8px;
	-webkit-border-bottom-right-radius: 8px;
	background: #f5faf5;
	border: 1px solid #BBCFBB;
	margin: 0;
	padding: 0;
	position: absolute;
	z-index: 999;
	top: 24px;
	left: -999em;
	height: 1px;
	display: block;
}

#userMenu .dropdown li {
	margin: 0;
	padding: 0;
	list-style: none;
	width: 145px;
}

#userMenu .dropdown li:hover {
	opacity: 1;
}

#userMenu .dropdown li a {
	display: block;
	padding: 6px 14px;
	text-shadow: 0px 0px 1px #fff;
}

#userMenu .dropdown li a:hover {
	text-decoration: none;
}

I’m a huge fan of CSS3 so I use border-radius quite liberally. Blitzaroo isn’t released yet so I haven’t added the Mozilla border-radius (-moz-border-radius) equivalent so you can either add it or remove the radius all together. The CSS itself is nothing special – I use display: block with a touch of padding on <a> tags and float <li> tags left for the parent so that we have a horizontal menu. With a slight change of the CSS you could create a vertical drop-down (slide out?) menu. I use left: -999em for accessibility (and for the Dojo animation we’ll be using).  So, with the addition of CSS the menu now looks like:

The JavaScript

I found the JavaScript on a tutorial to Create The Fanciest Dropdown Menu You Ever Saw which uses jQuery rather than Dojo. Personally, I think jQuery is over-hyped and I love Dojo (/me wipes nose). I took the JavaScript listed there, combined it with the mailing list love from Peter Higgins, and came up with:

dojo.addOnLoad(function() {
	// user menu special effects
	var userMenu = dojo.byId("userMenu");
	if (userMenu) {
		dojo.query(".dropdown").forEach(function(n) {
	    	var l = dojo.query(n);
	        l.parent().at(0)
				.onmouseenter(function(){
					dojo.style(l[0], "left", "0");
					dojo.fx.wipeIn({node: l[0], duration: 250}).play();
				})
				.onmouseleave(function(){
					dojo.style(l[0], "left", "-999em");
					dojo.style(l[0], "display", "none");
				});
	    });
    }
});

This little snippet recursively checks for .dropdown and when the mouse enters sets left: 0; followed by an animated Dojo wipeIn. On mouse out it sets left: -999em; and then sets the display to none. I tried a number of CSS/FX combinations to come up with a solution that worked and this is about all I could come up with. You could use any combination of Dojo FX to stylize your own menu. My favorites are wipeIn, wipeOut, fadeIn, and fadeOut combined with easing. Try out a few combinations and see what you like best. Enjoy!

Reblog this post [with Zemanta]
GD Star Rating
loading...
Creating fancy drop-down menus with HTML, CSS, and Dojo., 8.4 out of 10 based on 21 ratings
Categories: Dojo | Tags: Cascading Style Sheets, CSS, Data Formats, Dojo Toolkit, HTML, HTML element, JavaScript, Style Sheets

About SpiffyJr

View all posts by SpiffyJr→
Notice: This work is licensed under a BY-NC-SA. Permalink: Creating fancy drop-down menus with HTML, CSS, and Dojo.
Zend Calendar proposal
Creating a Twitter-esque login box with Dojo

15 Responses to “Creating fancy drop-down menus with HTML, CSS, and Dojo.”

  1. Dojo marketing and increasing the community | SpiffyJr's Blogaroo says:
    March 2, 2010 at 10:12 am

    [...] Creating fancy drop-down menus with HTML, CSS, and Dojo. [...]

  2. Alan Huffman says:
    March 9, 2010 at 8:19 am

    Nicely done sir!

    GD Star Rating
    loading...
  3. Andy Walpole says:
    April 13, 2010 at 10:58 am

    What’s this line of code here Spliffy?

    l.parent().at(0)

    l is the variable. Is parent() the Dojo equivalent of parentNode? And what does at(0) mean?

    GD Star Rating
    loading...
  4. SpiffyJr says:
    April 16, 2010 at 10:17 am

    Peter Higgins helped me out with that one. The n is the query result (

      …

    ). The l (lowercase L) is the parentNode which would be the

  5. ..
  6. , and I believe the .at(0) would be the first element. I suppose that’s not really needed in this example and the code seems to function fine without it.

    GD Star Rating
    loading...
  • SpiffyJr says:
    April 16, 2010 at 10:18 am

    Stupid HTML markup:

    1. <div>…</div>
    2. <li>…</li>

    Those should be in place of the “…” from above.

    GD Star Rating
    loading...
  • dojouser says:
    June 20, 2010 at 1:56 pm

    Great work, thank you very much!

    GD Star Rating
    loading...
  • yudhi says:
    July 4, 2010 at 9:38 am

    merci, this is very2 help me

    GD Star Rating
    loading...
  • Rob at Limeworks says:
    August 24, 2010 at 11:34 am

    Great stuff here!

    Not sure if it’s just me, but i found that dojo.NodeList-traverse needed to be included to call the parent() function.

    Rob

    GD Star Rating
    loading...
  • Dax says:
    September 29, 2010 at 3:25 pm

    Great method! I wanted to use this in my current project but apparently it only works in 1.4 and forware due to the Nodelist-Traverse. Does anyone know how to accomplish this functionality in 1.3.2? It’s the one I’m stuck with unfortunately. Thanks in advance.

    GD Star Rating
    loading...
  • Mario Guenterberg says:
    October 14, 2010 at 4:27 pm

    Hey man, you’ve saved my life. ;-) For my current ZF project I need a fancy menu, but I don’t want mixing different JS libraries. Great work!

    GD Star Rating
    loading...
  • 01 says:
    January 26, 2011 at 10:58 am

    Nice menu!
    Thank you!
    Just one problem with it… It doesn’t work correctly in IE. Firefox doesn’t produce any problems

    GD Star Rating
    loading...
  • lucky_girl says:
    February 18, 2011 at 1:43 am

    Great post! You must a expert on creating a menu:)

    GD Star Rating
    loading...
  • Chris says:
    May 11, 2011 at 10:03 am

    Hey great post!

    Have an issue though…

    It looks great on Google Chrome but doesn’t seem to appear the same way in IE7; the background colour and curved edges are missing and the menu extends right across the page?

    GD Star Rating
    loading...
  • Ludri says:
    May 26, 2011 at 4:35 am

    For 1.3 dojo i got it working with

    dojo.addOnLoad(function() {
    // user menu special effects
    var userMenu = dojo.byId(“userMenu”);
    if (userMenu) {
    dojo.query(“.dropdown”).forEach(function(n) {
    var l = dojo.query(n);
    var topdiv = dojo.query(l[0].parentNode.firstElementChild);
    topdiv.onmouseenter(function(){
    dojo.style(l[0], “left”, “0″);
    dojo.fx.wipeIn({node: l[0], duration: 250}).play();
    })
    .onmouseleave(function(){
    dojo.style(l[0], “left”, “-999em”);
    dojo.style(l[0], “display”, “none”);
    });
    });
    }
    });

    GD Star Rating
    loading...
  • Ludri says:
    May 26, 2011 at 5:08 am

    Uups. Went one level too low inside :)
    It should be:
    var topdiv = dojo.query(l[0].parentNode);

    Otherwise you can not access the submenus :D

    GD Star Rating
    loading...
  • Leave a Reply Cancel reply

    Your email address will not be published. Required fields are marked *

    *

    *


    question razz sad evil exclaim smile redface biggrin surprised eek confused cool lol mad twisted rolleyes wink idea arrow neutral cry mrgreen

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

    • Recent Posts

      • Keep your Git fork clean
      • Get started with Zend Framework 2 modules!
      • More Doctrine 2 and Zend Framework integration goodies!
      • Super sexy URLs with ZF and the joy of controller plugins!
      • Formatting your API to work with dojox.data.JsonRestStore (#dojo)
    • Categories

      • Other
        • Random
      • Projects
        • Blitzaroo
        • phpRaider
        • SpiffyDb
        • View Helpers
        • Zend Calendar
      • SpiffyJr
      • Technologies
        • Dojo
        • PHP
        • Zend Framework
    • Tag Cloud

        Ajax Algorithm api Blitzaroo Blog BSD licenses calendar Cascading Style Sheets CSS database Data Formats Dojo Dojo Toolkit event Framework game Google HTML HTML element JavaScript JQuery json Languages mapper Marketing mmorpg model php Programming Projects Scripts Source code Style sheet Style Sheets Twitter Website zend Zend Framework
    • Archives

      • December 2011
      • November 2011
      • July 2011
      • April 2011
      • March 2011
      • December 2010
      • November 2010
      • October 2010
      • March 2010
      • February 2010
      • November 2009
      • October 2009
      • September 2009
    © SpiffyJr's Blogaroo. Proudly Powered by WordPress | Nest Theme by YChong