Simple CSS drop down menu issues

I’m trying to work on a simple, pure CSS drop down menu and not having much luck. I’ve done this before with an un-ordered list, but in this case I’d rather not rebuild the entire top menu system if I can help it and stick with a non list style drop down menu if possible. I’ve tried some examples I’ve found but none of them are working. This is the code I’m currently working with:

CSS:

	/* Add a black background color to the top navigation */
	.topnav {
		background-color: black;
		overflow: hidden;
		font-family: Arial, Helvetica, sans-serif;
	}

	/* Style the links inside the navigation bar */
	.topnav a {
		float: left;
		color: #f2f2f2;
		text-align: center;
		padding: 14px 16px;
		text-decoration: none;
		font-size: 17px;
	}

	/* Change the color of links on hover */
	.topnav a:hover {
		background-color: gray;
		color: black;
	}

	/* Add a color to the active/current link */
	.topnav a:active {
		background-color: gray;
		color: white;
	}

	.topnav-right {
		float: right;
	}
	
	/* Create Dropdown Buttons */
	.topnav-child {
		display: none;
        background-color: gray;
	}
	
	.topnav-child a {
        padding: 20px;
        text-decoration: none;
        display: block;
    }

HTML

<div class="menubar">
	<div class=topnav>
	<a href=#>Home</a>
	<a href=#>About Us</a>
            <div class=topnav-child>
                <a href=#>Who We Are</a>
                <a href=#>What We Do</a>
                <a href=#>Code of Conduct</a>
            </div>
	<a href=#>Operations</a>
	<a href=#>Forums</a>
	<a href=#>Multimedia</a>
	<a href=#>Contact Us</a>
	<a href=#>Join Us!</a>
	</div>
</div>

The menu goes completely across the very top of the page. All I need this to do is just drop down once you hover over the initial link, and change colors in the child links as you hover over them. A working example of what it currently looks like sans drop down menus is here: http://www.vcaw1.com/.

Any tips or suggestions or where to look for more information would be great, and thank you.

It’s not possible with the structure you have to create a usable drop down.

Although I could give you code to make the drop down appear it would disappear before you could use it.

The css technique for showing a drop down requires the drop down to be enclosed in the element that is being hovered while it is shown. That’s why nested lists are perfect for this.

You could wrap a div around the trigger anchor and the drop down and then while that div is hovered you reveal the drop down. However if you are going to change the HTML to do this you may as well change it semantically to using the usual list structure. :slight_smile:

Let me know if you want help with either of the above.

1 Like

Ok Here’s the non semantic version based on your code but with a wrapping div added as mentioned.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
/* Add a black background color to the top navigation */
	.topnav {
	background-color: black;
	display:table;/* can't use overflow hidden to contain floats because we want the drop down to show oustide */
	width:100%;/* needed for display table to stretch*/
	font-family: Arial, Helvetica, sans-serif;
}
/* Style the links inside the navigation bar */
.topnav a {
	float: left;/* flexbox would be better*/
	color: #f2f2f2;
	background:#000;
	text-align: center;
	padding: 14px 16px;
	text-decoration: none;
	font-size: 17px;
	position:relative;
	z-index:100;
}
/* Change the color of links on hover */
.topnav a:hover {
	background-color: gray;
	color: black;
}
/* Add a color to the active/current link */
.topnav a:active {
	background-color: gray;
	color: white;
}
.topnav-right {
	float: right;
}
/* Create Dropdown Buttons */
.topnav-child {
	position:absolute;
	z-index:99;
	top:0;
	background-color: gray;
	left:-999em;/* hide offscreen*/
	opacity:0;
	transition:top .5s ease, opacity .3s ease,left 0s .5s;
}
.topnav-child a {
	padding: 20px;
	text-decoration: none;
	display: block;
	float:none;
	color:#fff;
}
.hasdrop {
	position:relative;
	float:left;
	z-index:99;
}
.hasdrop:hover div{left:0;top:100%;opacity:1;transition:top .5s ease, opacity .3s ease,left 0s;}
.hasdrop div,
.hasdrop div a {
	display:block;
	float:none;
	white-space:nowrap;
}
.hasdrop:hover > a{background:#ccc;color:#000;}
.hasdrop:hover div a:hover{background:red;color:#fff;}

</style>
</head>

<body>
<div class="menubar">
  <div class="topnav"> 
  	<a href=#>Home</a> 
  	<div class="hasdrop">
  		<a href=#>About Us</a>
    		<div class="topnav-child"> 
    			<a href=#>Who We Are</a> 
    			<a href=#>What We Do</a> 
    			<a href=#>Code of Conduct</a> 
    		</div>
    </div>
    <a href=#>Operations</a> 
    <a href=#>Forums</a> 
    <a href=#>Multimedia</a> 
    <a href=#>Contact Us</a> 
    <a href=#>Join Us!</a> 
    </div>
</div>
</body>
</html>

Note that these days we don’t tend to use floats any more for things like this but would instead use flexbox and avoid clearing issues etc.

Okay, thank you very much - that seems to work great.

Based on your comments though, I started experimenting with a list based menu system just to see the difference in code and placement. I managed to get it working so that it looks almost exactly the same - however, I’ve run into something I didn’t consider and am not sure how to fix it.

I need the base link across the top to work as an actual link as well, not just a vehicle / button for the drop down menu section. If I try to add an < a href > tag to the button itself it completely screws up the formatting. I’m sure this is something simple to fix, but I’m not sure how. When I was looking at this before, the was the main reason I wanted to avoid the list menu system, but if it’s possible to fix this issue I think I’ll probably go with the list based menu.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
* {
	margin: 0px;
	padding: 0px;
	box-sizing: border-box;
}

body {
	margin: 0;
	background: #cfcfd1;
}

.navbar {
	overflow: hidden;
	background-color: black;
	font-family: Arial, Helvetica, sans-serif;
}

.navbar a {
	float: left;
	color: white;
	text-align: center;
	padding: 14px 16px;
	text-decoration: none;
	font-size: 17px;
}

.dropdown {
	float: left;
	overflow: hidden;
}

.dropdown .dropbtn {
	font-size: 17px;  
	border: none;
	outline: none;
	color: white;
	padding: 14px 16px;
	background-color: inherit;
	font-family: inherit;
	margin: 0;
}

.navbar a:hover, .dropdown:hover .dropbtn {
	color: black;
	background-color: gray;
}

.dropdown-content {
	display: none;
	position: absolute;
	background-color: #a2a2a3;
	min-width: 160px;
	box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
	z-index: 10;
}

.dropdown-content a {
	float: none;
	color: black;
	padding: 12px 16px;
	text-decoration: none;
	display: block;
	text-align: left;
}

.dropdown-content a:hover {
	background-color: red;
}

.dropdown:hover .dropdown-content {
	display: block;
}

.navbar-right {
	float: right;
}
</style>
</head>
<body>

<div class="navbar">
	<a href="#">Home</a>
	<div class="dropdown">
		<button class="dropbtn">About Us</button>
		<div class="dropdown-content">
			<a href="#">Who We Are</a>
			<a href="#">What We Do</a>
			<a href="#">Code of Conduct</a>
		</div>
	</div>
	<div class="dropdown">
		<button class="dropbtn">Operations</button>
		<div class="dropdown-content">
			<a href="#">Who We Are</a>
			<a href="#">What We Do</a>
			<a href="#">Code of Conduct</a>
		</div>
	</div>
	<a href="#">Forums</a>
	<div class="dropdown">
		<button class="dropbtn">Multimedia</button>
		<div class="dropdown-content">
			<a href="#">Screenshots</a>
			<a href="#">Videos</a>
		</div>
	</div>
	<a href="#">Contact Us</a>
	<a href="#">Join Us!</a>
	<a href="#">S.H.A.R.P.</a>
	<div class=navbar-right>
		<a href=#>Training Status</a>
		<a href=#>Log In</a>
		<a href=#>Register</a>
	</div>
</div>

</body>
</html>
1 Like

Did you post the wrong code there are no lists in that code you posted? I’m a little confused :slight_smile:

A list is made using an opening ul tag followed by li tags etc…

The button element and the anchor element are mutually exclusive you can’t nest interactive elements (it would be like nesting an anchor inside another anchor).

Just use anchors along the top and you will be fine.

As I said you can’t add an anchor to a button so just use an anchor and style it accordingly. The reason it won’t work in your example with an anchor is because you left out the important points that I commented on in my code.

You use overflow:hidden which is causing problems and you need to use position:relative on the parent of the drop down to allow for a proper stacking context.

You are also using display:none which I advised against as that hides it from search engines and assistive technologies. It’s best to hide the menu off screen and that also allows you to animate smoothly as in the example I gave you. animating the menu is important to accessibility as it gives you a little time for shaky hands to move on and off the menu before its gone.

Here’s your html and css revised (apart from the animations as you can see those in my original demo).

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
* {
	margin: 0px;
	padding: 0px;
	box-sizing: border-box;
}

body {
	margin: 0;
	background: #cfcfd1;
}

.navbar {
	/*overflow: hidden; no no no */
	display:table;/* yes yes yes */
	width:100%;/* yes yes yes */
	background-color: black;
	font-family: Arial, Helvetica, sans-serif;
}
.navbar a {
	float: left;
	color: white;
	text-align: center;
	padding: 14px 16px;
	text-decoration: none;
	font-size: 17px;
	position:relative;
}
.dropdown {
	float: left;
	/*overflow: hidden; no not needed*/
	position:relative;/* very important*/
}
.navbar a:hover, .dropdown:hover > a {
	color: black;
	background-color: gray;
}

.dropdown-content {
	/* display: none;no no no */
	position: absolute;
	left:-999em;/* hide off screen */
	top:100%;
	background-color: #a2a2a3;
	min-width: 160px;
	box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
	z-index: 10;
}

.dropdown-content a {
	float: none;
	color: black;
	padding: 12px 16px;
	text-decoration: none;
	display: block;
	text-align: left;
}

.dropdown-content a:hover {
	background-color: red;
}

.dropdown:hover .dropdown-content {
	/*display: block; don't need this now */
	left:0;/* very important to show menu */
}

.navbar-right {
	float: right;
}
</style>
</head>
<body>

<div class="navbar">
	<a href="#">Home</a>
	<div class="dropdown">
		<a href="#" class="dropbtn">About Us</a>
		<div class="dropdown-content">
			<a href="#">Who We Are</a>
			<a href="#">What We Do</a>
			<a href="#">Code of Conduct</a>
		</div>
	</div>
	<div class="dropdown">
		<a href="#" class="dropbtn">Operations</a>
		<div class="dropdown-content">
			<a href="#">Who We Are</a>
			<a href="#">What We Do</a>
			<a href="#">Code of Conduct</a>
		</div>
	</div>
	<a href="#">Forums</a>
	<div class="dropdown">
		<a href="#" class="dropbtn">Multimedia</a>
		<div class="dropdown-content">
			<a href="#">Screenshots</a>
			<a href="#">Videos</a>
		</div>
	</div>
	<a href="#">Contact Us</a>
	<a href="#">Join Us!</a>
	<a href="#">S.H.A.R.P.</a>
	<div class=navbar-right>
		<a href=#>Training Status</a>
		<a href=#>Log In</a>
		<a href=#>Register</a>
	</div>
</div>

</body>
</html>

I’ll show you a version based on a list structure but it won’t be until tomorrow as I am offline now :slight_smile:

Don’t worry if you are still confused I’ll explain tomorrow when I have more time but just have a play around and see if you can work out what’s what. :wink:

1 Like

As promised here is how it would look in a semantic list structure.

Note that I removed all floats as I don’t use them these days and use flexbox instead.

Your next steps would be to work out how to make this more responsive and also how you are going to support mobile that doesn’t work well with hover effects (as there is no real hover on mobile).

Uh - wow, you’re right… I pasted the wrong code. Apologies for that; I was in a bit of a hurry to finish up the post and apparently had cut / copied that test file rather than the one with the list without realizing it.

Thanks for the Codepen example - and the transition effect also, as that’s not something I would have thought of. That will work perfectly with some slight changes (mostly just background images to replace the background colors).

As for mobile, I’ve been thinking about that - I’m not sure I’m going to really put a high priority on that though, considering this site is essentially a game group site that is based around a Windows game that’s not available for mobile or non-Windows platforms. That being said, for those who do use it’s logged in database features, being mobile friendly couldn’t hurt.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.