Touchy Drop-Down Sub-Menu

Hey Good Folks,

I just added three pages to my website (www.drumdr.com), and decided to link to them through a sub-menu so as to keep the clutter down. It also makes sense because the three new pages really are sub-topics to a page already there (www.drumdr.com/hand-drum.html. The new pages are on African, Middle Eastern and Indian drums).

Here’s the thing; the sub menu is really touchy. It shows up fine with a mouse-over, but unless your’e really quick with the mouse, you’ll miss it when you try to click on it. The other thing is that I don’t really like that the sub-menu covers part of the main menu. Is there any way to have the sub menu pop up beside the main menu?

Below please find the relevant code. Notice that I’m going with pure HTML and CSS. I’d like to stick with that if at all possible.

Thanks in advance,
jcmcobra

	<div id="sideBar">
		<ul id="mainMenu">
			<li><a href="index.html">Home</a></li>
			<li><a href="about-drum-repair.html">About Drum Dr.</a></li>
			<li><a href="hand-drum.html">Hand Drums</a>
                                <ul>
                                    <li><a href="african-hand-drums.html">African Hand Drums</a></li>
                                    <li><a href="middle-eastern-hand-drums.html">Middle Eastern Hand Drums</a></li>
                                    <li><a href="indian-hand-drums.html">Indian Hand Drums</a></li>
                                </ul>
                            </li>
			<li><a href="drum-repair-histories.html">Drum Repair Histories</a></li>
			<li><a href="djembe-repair.html">Djembe Repair</a></li>
			<li><a href="djembe-history.html">Djembe History</a></li>
			<li><a href="tabla-repair.html">Tabla Repair</a></li>
			<li><a href="drum-doctor-contact.html">Drum Dr. Contacts</a></li>
			<li><a href="repair-rates.html">Drum Repair Rates</a></li>
			<li><a href="drumming-events.html">Drumming Events</a></li>
		</ul>
	<!-- #sideBar --></div>

#sideBar {
float:left;
width:192px;
}

#mainMenu {
list-style:none;
padding:12px;
font:bold 14px/18px verdana,helvetica,sans-serif;
}

#mainMenu li {
display:inline; /* just get these out of the way! */
}

#mainMenu a {
display:block;
padding:6px 8px;
margin-bottom:6px;
text-decoration:none;
color:#000;
background:#FFF8F0;
border:1px solid #FDB;
-moz-border-radius:12px;
-webkit-border-radius:12px;
border-radius:12px;
}

#mainMenu a:active,
#mainMenu a:focus,
#mainMenu a:hover {
background:#FED;
}

#mainMenu li ul {
display: none;
}

#mainMenu li:hover ul {
display: block;
position: absolute;
}

#mainMenu li:hover ul li a {
display:block;
padding:6px 8px;
margin-bottom:0;
text-decoration:none;
background:white;
color:#000;
border:1px solid #FDB;
-moz-border-radius:12px;
-webkit-border-radius:12px;
border-radius:12px;
}

#mainMenu li:hover ul li a:hover {
background:#6dc7ec;
color:#fff;
}

You should position the submenu with absolute positioning so it is removed from the flow and then place it at the side.

The extra code to do that is as follows:



#mainMenu li{position:relative}
#mainMenu li li{display:block}
#mainMenu li ul{
position:absolute;
left:160px;
margin-left:-999em;
top:-20px;
display:block;
width:150px;
}
#mainMenu li:hover{z-index:999}
#mainMenu li:hover ul{
margin:0;
}


The menu is hidden off left initially with a large negative margin and then brought back on by reducing the margin rather than using display:none which is buggy in old IE and bad for accessibility.

Menu items must touch the submenu or you will lose focus before you can get to it.

Thanks Paul,

Your suggestion gets me the sub-menu on the side just fine, but it ruins my main menu’s formatting, and I don’t understand why. The only line that should affect my main menu is

#mainMenu li{position:relative}

which has replaced

#mainMenu li {display:inline; /* just get these out of the way! */}

The only other line I’ve removed from the original code is

#mainMenu li ul {
display: none;
}

which is replaced by

#mainMenu li ul{
position:absolute;
left:160px;
margin-left:-999em;
top:-20px;
display:block;
width:150px;
}

???

Hi,

I just tested the code I gave you again and it seems to have no effect on the formatting of your existing menu (just fire up css terminal and paste the code I gave you and changes will be seen straight away on your live site).

The code I gave was additional and you didn’t actually need to change anything else so you must have inadvertently changed something along the way or you are running into a specific browser bug that I didn’t see.

If you are still having problems you will have to put the code live for use to debug further.

You’re right Paul - it is a browser thing.

I’ve been using Chromium, and the first thing I did was to simply cut and paste your code. Nothing happened, so that’s when I tried deleting a couple of the original lines.

I just tried it with Firefox and it worked just fine.

When I gave you the help on that code originally (thought that looked familiar, view source confirmed it), I didn’t build the menu with submenus in mind… what’s messing you up is the display:inline on the LI – which I do so IE7 isn’t a royal pain in one’s backside. That’s really what needs to be removed and a haslayout trigger added.

I would also advise against the display:none approach to handling the hover… and instead use overflow:hidden to chop it off…

So something like:


#mainMenu {
	list-style:none;
	padding:12px;
	font:bold 14px/18px verdana,helvetica,sans-serif;
}

#mainMenu li {
	display:block;
	overflow:hidden;
	width:168px;
	padding-bottom:6px;
}

#mainMenu li:hover {
	overflow:visible;
}

#mainMenu a {
	display:block;
	padding:6px 8px;
	text-decoration:none;
	color:#000;
	background:#FFF8F0;
	border:1px solid #FDB;
	-moz-border-radius:12px;
	-webkit-border-radius:12px;
	border-radius:12px;
}

#mainMenu a:active,
#mainMenu a:focus,
#mainMenu a:hover,
#mainMenu li:hover a {
	background:#FED;
}

#mainMenu ul {
	list-style:none;
	position:absolute;
	top:0;
	left:168px;
	width:224px;
}

#mainMenu li li {
	width:auto;
}

#mainMenu li:hover li a {
	background:#FFF;
}

#mainMenu li li:hover a {
	color:#FFF;
	background:#6DC7EC;
}

Should do the trick… though you’d want to play with the width on the nested UL. Getting rid of the margins and using the extra element on the height should help with the mouse-over oddities too – sometimes when you mouse-over margins some browsers treat it as leaving the PARENT element, which makes no sense, but that’s browsers for you.

Really though, I’ve found the past few months that playing with display:none and display:block or sliding absolute positioned elements around just for a hover is a buggy unreliable waste of time; positioning it once and then showing/hiding it by changing the parent elements overflow state works much better, and makes the whole thing so much simpler.

Just be warned the LI may ‘bounce up and down’ in height in IE7 when hovered – using bottom padding on the LI instead of margin on the anchor SHOULD fix that, but no guarantees as, well… we’re talking about IE.

Hey deathshadow60,

Thanks for that. Your suggestions result in no formatting changes to the main menu, and the sub-menu pops up to right at absolute 0. That is, it’s positioned at the top of the page. This is the result of:

#mainMenu ul {
list-style:none;
position:absolute;
top:0;
left:168px;
width:224px;
}

I’ve tried adjusting the position from the top, but any value other than 0 (including negative values) places the sub-menu to the right and immediately below the parent element. I don’t get this. The mouse-over issue persists.

Thanks again,
jcmcobra

Doh, what I get for posting 3 hours past bedtime with insomnia. That’s a my bad.

change:


#mainMenu li {
	display:block;
	overflow:hidden;
	width:168px;
	padding-bottom:6px;
}

to:


#mainMenu li {
	positon:relative;
	display:block;
	overflow:hidden;
	width:168px;
	padding-bottom:6px;
}

That way top/left 0 0 is based on the LI, not the page. Stupid omission on my part.

Same result; any value other than 0 places the sub-menu immediately below and to the right.

Actually, this is quite functional. The sub-menu does not cover any of the main menu, and if you go from bottom corner of parent element to top-left corner of sum-menu it functions just fine. It would be nice to understand why any value other than 0 places the sub-menu precisely there, though. I don’t get it.

As it is this is a good improvement, and I appreciate your help.

Top:0 should be inline with it… right now you are saying 1… the question being 1 WHAT? EM? PX? Quijadas? Tacos?

Zero is always zero - you don’t need to say what zero is – you specify a number you probably should be saying WHAT it is. Top:0 should be top aligned… I’m not sure what problem you are having with zero on it, seems to work as expected here.

I’d be using the zero – not sure why you’d even be playing with that.

You don’t seem to have added the position relative that Jason gave you above.

e.g.



#mainMenu li{position:relative}
#mainMenu li ul{top:0}

It’s the position:relative that creates the stacking context for the sub menu.

I’m pretty sure you mean

#mainMenu li {top:0}

Anyway, I checked and triple checked and all is as suggested. When I tried other values from the top I was neglecting to specify the units.

CSS Terminal seems like a really useful tool. Thanks for pointing it out to me.

Wow! You know quijadas? Now I’m really impressed.

You’re right - I neglected to specify the units. Going with pixels I’ve been able to maneuver the sub-menu to a position more to my liking. I still don’t get why any value other than 0 placed the sub-menu immediately to the right and below the parent element. I’ll have to study that when I get a chance.

No, he means “#mainMenu li ul” as the UL is what needs to be positioned. The outer LI gets relative, the UL inside that LI gets top:0;

Off Topic:

Timbale, Agogo, Conga, Cowbell, Koto, Marimba, castanets…

I’m a musician too – and been programming midi for fun for over two decades; I have a working knowledge of percussion, though I’m more of a woodwind guy

I still don’t get why any value other than 0 placed the sub-menu immediately to the right and below the parent element. I’ll have to study that when I get a chance.

The position:relative on the LI means that top:0; left:0; of all children inside it when absolute positioned is that LI’s top/left corner. On the UL that means ‘top:0’ would be inline with the LI… and anything greater than zero would be down from that. Notice also that left:168px; is being set – pushing the menu over the same as the LI’s width – hence it being to the right.

If you want to move it up, you’d use a negative top value… like top:-1em; would move it up one em.

Your talents never cease to amaze me :slight_smile:

No, he means “#mainMenu li ul” as the UL is what needs to be positioned. The outer LI gets relative, the UL inside that LI gets top:0;

We seem to be on a similar page, but not the same one. You didn’t suggest

           #mainMenu li ul{top:0}

though I did try it when Paul first brought it up (just in case), and it didn’t help. I just tried it again (just in case) and it didn’t help.

Your (amended) suggestions worked really well once I changed the top: 0; to top:162px; and added the following code just for the sake of aesthetics:

          /* no space between sub-menu links */
          #mainMenu li ul li {
                    padding:0;
          }

On the UL that means ‘top:0’ would be inline with the LI… and anything greater than zero would be down from that. Notice also that left:168px; is being set – pushing the menu over the same as the LI’s width – hence it being to the right

No. I think I get what’s going on. mainMenu is the top-level UL, which gets the default position , since none is is specified. It’s at the top left corner. The next UL mentioned is the nested list and it goes wherever we tell it to. In this case

#mainMenu ul {
list-style:none;
position:absolute;
top:162px;
left:168px;
width:224px;
}

puts it immediately centered and to the right of its parent. N’est-ce pa?

It shouldn’t, that should be so far down the page you can’t even mouse-over to it… unless you’re NOT getting the position:relative on your LI.

Ok, what you seem to have is constantly setting and unsetting values – what I posted above was supposed to replace the ENTIRE menu declaration in your CSS, not just part of it… you’ve got all sorts of confused and conflicted values overriding each-other in there – you STILL have the display:none and display:block nonsense…

EVERYTHING in your CSS starting with #mainMenu was supposed to be replaced by the code I posted, just with the position:relative I forgot on the LI added. You’ve still got half your old code in there after it, and that’s completely messing up positioning.

For example these:


#mainMenu li ul {
       display: none;
}

/* no space between sub-menu links */
#mainMenu li:hover ul {
        display: block;
        position: absolute;
}

Shouldn’t even be in there! My code changing overflow on hover supplants that… then this:


#mainMenu li:hover ul li a {
        display:block;
	padding:6px 8px;
	margin-bottom:0;
	text-decoration:none;
        background:white;
        color:#000;
	border:1px solid #FDB;
	-moz-border-radius:12px;
	-webkit-border-radius:12px;
	border-radius:12px;
}

is redundant to this, which declares mostly the same thing!


#mainMenu a {
	display:block;
	padding:6px 8px;
	text-decoration:none;
	color:#000;
	background:#FFF8F0;
	border:1px solid #FDB;
	-moz-border-radius:12px;
	-webkit-border-radius:12px;
	border-radius:12px;
}

Only declare things that are DIFFERENT on child items, because they inherit… as such all that second one needs to read is:


#mainMenu li:hover ul li a {
	background:white;
}

All the rest of that is already set!


#mainMenu li li {
	width:auto;
}

auto-width in floats is unpredictable cross browser – it’s why flyouts and their parents generally have to be fixed width. (part of why I don’t use them anymore and just use normal sub-navigations because, well, page-loads aren’t evil)

Even so though, that massive top amount doesn’t make any sense if the LI are getting position:relative;

Ok, give me some time to try and get a handle on this.

Thanks for the lesson. I took the time to review SELECTORS, and I’m glad I did. Fairly simple, but important stuff that I’d neglected until now. I’m learning as I go. Until now, I really hadn’t given a thought to INHERITANCE either.

You’re right, of course. I’ve gotten rid of the extraneous code and simply removed the padding from the sub-menu. I have what I was shooting for and learned something in the process.

Thank you again for your patience and your generosity.

jcmcobra