CSS3 Menus

Contact Us or call 1-877-932-8228
CSS3 Menus

CSS3 Menus

Dropdown Menus

All of the code we've looked at so far works fine for modern browsers. But we can leverage some of the new powers that CSS3 gives us to remake our dropdown menus. Using the same markup - that is, the same set of nested unordered lists - let's look at how we might use some CSS3 features to render our dropdown menus. As always, we'll need to keep in mind that some newer CSS3 features won't work in older browsers.

Code Sample:

CssListMenus/Demos/CssMenu-dropdown-css3.html
---- C O D E   O M I T T E D ----
<link type="text/css" rel="stylesheet" href="../reset-meyer.css">
<style type="text/css">	
	nav { 
		background-color: #ff7800;
		font-family: "Trebuchet MS";
		position:relative;
	}

	nav:after {
		clear:left;
		content:"";
		display:table;
	}

	nav ul {
		padding:0;
		margin:0;
		list-style: none;
		position: relative;
	}
		
	nav ul li {
		margin: 0px;
		display:inline-block;
		float: left;
		background-color: #ff7800;
	}
	
	nav ul a {
		display:block;
		padding:0 20px;	
		color:#FFF;
		font-size:14px;
		line-height: 50px;
		text-decoration: none;
		transition: background-color 1.0s;
	}

	nav a:hover { 
		background-color: #000000;
	}

	nav ul ul {
		visibility:hidden;
		opacity: 0;
		position: absolute;
		top: 50px;
		transition:opacity 1.0s;
	}
		
	nav ul li:hover > ul {
		visibility:visible;
		opacity: 1;
	}

	nav ul ul li {
		float:none;
		display:list-item;
		position: relative;
	}
	
	li > a:after {
		content:  ' +';
	}
	
	li > a:only-child:after {
		content: '';
	}
</style>
<title>CSS Menu</title>
</head>
<body>
<nav>
	<ul id="mainMenu">
		<li><a href="home.html">Home</a></li>
		<li><a href="services.html">Services</a></li>
		<li><a href="products.html">Products</a></li>
		<li><a href="support.html">Support</a></li>
		<li><a href="blog.html">Blog</a></li>
		<li><a href="about.html">About</a>
			<ul>
				<li><a href="history.html">Company History</a></li>
				<li><a href="staff.html">Our Staff</a></li>
				<li><a href="press.html">Press Releases</a></li>
				<li><a href="investorInfo.html">Investor Information</a></li>
			</ul>
		</li>
		<li><a href="contact.html">Contact</a></li>
	</ul>
</nav>
</body>
</html>

Code Explanation

Our HTML code is the same, but for the addition of an HTML5 nav element, wrapping the menu list. We give the nav an orange background color:

CSS3 menu

Since we float the top-level list items left, we add clear:left to nav:after, so that the nav element spans the entire width of the screen.

We style the top-level links (the a tags) to display:block and give them a line-height of 50px to give depth to the menu.

We style the links to change background color on hover, and use a transition to fade in/out the background color over a duration of 1.0 second.

For the dropdown menus, we set nav ul ul (the child lists) to have an initial visibility of hidden and opacity of 0. The visibility changes on hover so that the menus appear; we use the opacity, which also changes (to 1) on hover, so that we can animate it with a transition. (Visibility is not a CSS property that is animatable via transitions.) We un-float the second-level list items so that they appear vertical.

Lastly, we use li > a:after to give all list item links a "+" character, then use li > a:only-child:after to apply this only to those elements which do have a subsidiary (child) list.

A Mobile-Frienly Menu

We can extend our CSS3 menu to work for users who visit our pages on a smartphone. Using a media query, we can render our menu differently when viewed from a browser whose width is less than a given threshold.

Code Sample:

CssListMenus/Demos/CssMenu-dropdown-css3-mobile.html
---- C O D E   O M I T T E D ----
<link type="text/css" rel="stylesheet" href="../reset-meyer.css">
<meta name="viewport" content="width=device-width">
<style type="text/css">	
	nav { 
		background-color: #ff7800;
		font-family: "Trebuchet MS";
		position:relative;
	}

	#menutoggle {
		width: 40px;
		height: 50px;
		position: relative;
		float:right;
		margin-right:10px;
		display:none;
	}

	#menutoggle:hover {
		background-color: transparent;
	}

	#menutoggle:before {
		content: "";
		position: absolute;
		left: 0;
		top: 10px;
		width: 40px;
		height: 5px;
		background: black;
		box-shadow: 0 12px 0 0 black, 0 24px 0 0 black;
	}

	nav:after {
		clear:left;
		content:"";
		display:table;
	}

	nav ul {
		padding:0;
		margin:0;
		list-style: none;
		position: relative;
	}

	nav ul li {
		margin: 0px;
		display:inline-block;
		float: left;
		background-color: #ff7800;
	}

	nav ul a {
		display:block;
		padding:0 20px;
		color:#FFF;
		font-size:14px;
		line-height: 50px;
		text-decoration:none;
		transition: background-color 1.0s;
	}

	nav a:hover { 
		background-color: #000000;
	}

	nav ul ul {
		visibility:hidden;
		opacity: 0;
		position: absolute;
		top: 50px;
		transition:opacity 1.0s;
	}
		
	nav ul li:hover > ul {
		visibility:visible;
		opacity: 1;
	}
		
	nav ul ul li {
		float:none;
		display:list-item;
		position: relative;
	}

	li > a:after {
		content:  ' +';
	}

	li > a:only-child:after {
		content: '';
	}

	@media only screen and (max-width : 700px) {

		#menutoggle {
			display:inline-block;
		}

		nav ul { 
			display: none;
			width: 100%;
		}

		nav li {
			text-align: left;
			width: 100%;
			padding: 2px 0;
			border-bottom:1px solid #fff;
			margin: 0;
		}

		nav:hover > ul {
			display: block;
		}

		nav ul li:hover ul {
			display: block;
			visibility:visible;
			opacity: 1;
			position:static;
		}

		nav ul li ul li {
			text-align: left;
			padding: 1px 0 1px 10%;
			width:90%;
			font-size:12px;
			border-bottom:none;
			margin: 0;
		}
	}
</style>
<title>CSS Menu</title>
</head>
<body>
<nav>
	<a href="#" id="menutoggle"></a>
	<ul id="mainMenu">
		<li><a href="home.html">Home</a></li>
		<li><a href="services.html">Services</a></li>
		<li><a href="products.html">Products</a></li>
		<li><a href="support.html">Support</a></li>
		<li><a href="blog.html">Blog</a></li>
		<li><a href="about.html">About</a>
			<ul>
				<li><a href="history.html">Company History</a></li>
				<li><a href="staff.html">Our Staff</a></li>
				<li><a href="press.html">Press Releases</a></li>
				<li><a href="investorInfo.html">Investor Information</a></li>
			</ul>
		</li>
		<li><a href="contact.html">Contact</a></li>
	</ul>
</nav>
</body>
</html>

Code Explanation

The desktop version of our page looks exactly the same as before. But when the browser is narrower than 700px, our media query takes over and the user sees the phone-friendly navigation:

mobile menu

Other than CSS changes, we add only two things to our page: a viewport meta tag (to ensure that the page renders appropriately on smaller screens) and the <a href="#" id="menutoggle"></a> menu toggle link, just inside the nav element but before the unordered list menu. We hide the menu toggle link for larger screens, but show it (with display:inline-block) inside the media query.

Inside the media query - that is, when the width of the viewport is less than 700px - we set the unordered list menu to initially display: none. When the user mouses over the nav element, we set the list menu to display: block. This displays the menu, pushing down any content under it.

We style the sub-list to show when the user mouses over its parent (the "About" element), indenting the sub-nav and removing its borders.

Next