Skip to Content

Every once in a while you need a drop down navigation that can house a lot of links. For a long time I fought doing something like this because it can be pretty hideous. Finally, I gave in and decided to try to do it in a way that didn’t suck (too bad).

HTML

<!-- here's just a big dumby unordered list; standard markup. -->
<nav>
	<ul class="big">
		<li><a href="#">Savory</a>
			<ul>
				<li><strong>Cheese</strong>
					<ul>
						<li><a href="#">Munster</a></li>
						<li><a href="#">Cheddar</a></li>
						<li><a href="#">Swiss</a></li>
						<li><a href="#">Monterray</a></li>
						<li><a href="#">Mozarella</a></li>
						<li><a href="#">Asiago</a></li>
						<li><a href="#">Romano</a></li>
						<li><a href="#">Parmegiana</a></li>
					</ul>
				</li>
				<li><strong>Herbs</strong>
					<ul>
						<li><a href="#">Basil</a></li>
						<li><a href="#">Oregano</a></li>
						<li><a href="#">Thyme</a></li>
						<li><a href="#">Marjoram</a></li>
						<li><a href="#">Savory</a></li>
						<li><a href="#">Taragon</a></li>
						<li><a href="#">Rosemary</a></li>
					</ul>
				</li>
			</ul>
		</li>
		<li><a href="#">Sweet</a>
			<ul>
				<li><strong>Candies</strong>
					<ul>
						<li><a href="#">Zots</a></li>
						<li><a href="#">Sourheads</a></li>
						<li><a href="#">Old Fashioned Hard Candy</a></li>
						<li><a href="#">Gobstoppers</a></li>
						<li><a href="#">Charleston Chew</a></li>
						<li><a href="#">FunDips</a></li>
					</ul>
				</li>
				<li><strong>Pastries</strong>
					<ul>
						<li><a href="#">Apple Fritter</a></li>
						<li><a href="#">Cream Cheese Danish</a></li>
						<li><a href="#">Pecan Roll</a></li>
						<li><a href="#">Chocolate Croissant</a></li>
						<li><a href="#">Cheese Puff</a></li>
					</ul>
				</li>
				<li><strong>Other</strong>
					<ul>
						<li><a href="#">Sugar</a></li>
						<li><a href="#">Molasas</a></li>
						<li><a href="#">Honey</a></li>
					</ul>
				</li>
			</ul>
		</li>
	</ul>
</nav>

CSS

nav {
	/* basic text properites; these could be set higher up the DOM, but for the example we'll put them here. */
	font-size:16px; /* normally should be set in em, but this is to override some of my site styles. */
	line-height:1.2em;
}
ul.big {
	margin:0;
	padding:0;
	height:2.2em; /* Must equal: line-height + total padding on links (1.2em + (0.5em x 2) = 2.2em) */
	background-color:#666;
	color:#fff;
}
ul.big li {
	margin:0;
	padding:0;
	list-style:none;
	display:inline;
	float:left;
	position:relative;
}
ul.big li a {
	display:block;
	float:left;
	color:#fff;
	background-color:#666;
	padding:0.5em 0.75em;
	text-decoration:none;
}
ul.big li a:hover {
	background-color:#333;
	text-decoration:underline;
}
ul.big li.over > a {
	background-color:#333;
	padding-top:0.4em;
	border-top:2px solid #39F;
}
ul.big li ul {
	display:none;
	padding:0;
	margin:0;	
}
ul.big li:hover ul {
	display:block;	
}
ul.big > li > ul {
	padding:0.8em 1em;
	background-color:#333;
	position:absolute;
	top:2.2em; /* equal to the noted height above */
}
ul.big > li.parent_2 > ul {
	width:28em;
}
ul.big > li.parent_3 > ul {
	width:42em;
}

ul.big li ul li,
ul.big li ul li a {
	display:block;
	float:none;	
}
ul.big > li > ul > li > strong {
	display:block;
	background-color:#555;
	padding:0.2em 0.8em;
}
ul.big li ul li ul li a {
	background-color:transparent;
	border-bottom:1px dotted #555;
	font-size:0.9em;
	padding:0.4em 0.8em;
}
ul.big > li > ul > li {
	width:12em;
	padding:1em;
	float:left;
}

Javascript

/* a bit of nifty scripty to determine how many columns to use. */
$(function(){
	$('.big').each(function(){
		var parents = $(this).children('li');
		parents.each(function(){
			$(this).hover(function(){
				$(this).addClass('over');
			},function(){
				$(this).removeClass('over');
			});
			var children_count = $(this).children('ul').children('li').length;
			if (children_count == 2) {
				$(this).addClass('parent_2');
			} else if (children_count > 2) {
				$(this).addClass('parent_3');
			}
		});
	});
});