Hi I have a horizontal rollover menu with a horizontal submenu

I want the submenu to stay out when the use moves his cursor off the menu item unless the user rolls over another menu item

like on this site

now I know that is a flash menu, but is it possible to do this in css.

I have menu working fine, but it can be quite tricky for the user to scroll along the horizontal submenu as it pops back up if the users mouse slightly strays off the submenu which is pretty narrow

many thanks in advance

my menu(which is dynamically created from a database)

<style>
#topmenu,#topmenu ul {padding:0;margin:0; }


#topmenu li {
	float:left;
	width:120px;
	position:relative;
	list-style-type:none;		
	color:#000000;
	font-family:Arial, Helvetica, sans-serif;
	font-size:14px;
	font-weight:bold;
	text-align:center;
	line-height:50px;
	height:50px;
	background-image:url(images/menu_yellow_bg.png);
	background-repeat:repeat-x;
	
}
#topmenu li a:link{
	
	color:#000;
	text-decoration:none;
	
}
#topmenu li a:visited{
	
	color:#000;
	text-decoration:none;
}
#topmenu li:hover{
	float:left;
	width:120px;
	position:relative;
	list-style-type:none;		
	color:#000;
	font-family:Arial, Helvetica, sans-serif;
	font-size:14px;
	font-weight:bold;
	text-align:center;
	line-height:50px;
	background-image:url(images/menu_grey_bg.png);
	background-repeat:repeat-x;
	text-decoration:none;
}

#topmenu li a:hover{	
	color:#000;
	width:120px;
	height:50px;
	line-height:20px;
}



fieldset p {clear:left;}



#topmenu li:hover ul,
#topmenu li.msieFix ul {
	visibility:visible;
	width:0px;	
	color:#000;
	line-height:20px;
}

* html fieldset p {z-index:-1}
* html #topmenu li:hover ul,
* html #topmenu li.msieFix ul {
	top:50px;
	left:0px;
	color:#000;	
}


#topmenu li ul {
	visibility:hidden;
	position:absolute;
	width:0px;
	color:#000;
	text-align:left;
	line-height:20px;
	top:48px;
	left:0px;	
	 
}

#topmenu li ul li { width:100%;padding-top:2px;line-height:20px; text-align:left; padding-left:0px; height:22px;	}
#topmenu li ul li:hover { width:100%; color:#ffffff; line-height:20px; text-align:left;}

#topmenu li ul a {margin-left:0px; width:100%;color:#ffffff;text-align:center;font-family:Arial, Helvetica, sans-serif;font-size:11px;font-weight:bold;}
#topmenu li ul a:hover { width:100%;color:#979797; }
.low1
{
	position:absolute;
	width:100px;
	left:0px;
	text-align:center;
	background-color:#CCCCCC;
	
}
.low2
{
	position:absolute;
	width:105px;
	left:100px;
	text-align:center;
	background-color:#CCCCCC;
}
.low3
{
	position:absolute;
	width:100px;
	left:205px;
	text-align:center;
	background-color:#CCCCCC;

}
.low4
{
	position:absolute;
	width:90px;
	left:305px;
	text-align:center;
	background-color:#CCCCCC;

}
.menu_end_left
	{
		position:absolute;
		left:-13px;
		width:13px;
		height:100%;
		background-image:url(images/menu_yellow_left.png);
		background-repeat:no-repeat;
		z-index:2000
	}
.menu_end_right
	{
		position:absolute;
		left:600px;
		width:13px;
		height:100%;
		background-image:url(images/menu_yellow_right.png);
		background-repeat:no-repeat;
		z-index:2000
	}
.top_item
	{
		position:absolute;
		top:0px;
		height:52px;
		width:100%;
		left:0px;
		border:0px solid red;
		line-height:50px;
	}
.text
	{
		line-height:52px;
	}
	
	
</style>
<ul id="topmenu">
	<span class="menu_end_left"></span>
	<?
	
	$sql=mysql_query("SELECT * FROM menu ORDER BY position ASC");
	while($row=mysql_fetch_array($sql))
		{
		$ref=$row['ref'];
	?>
		<li onmouseover="this.className='msieFix'" onmouseout="this.className=''" >
			<?  if($row['link']!='')
					{
						?><a class="top_item" href="<? echo $pre.$row['link']; ?>"><span class="text"><? echo $row[$lang]; ?></span></a><?
					}
				else
					{
						?><span class="text"><? echo $row[$lang]; ?></span><?
					}			
							
					$sql_sub=mysql_query("SELECT * FROM submenu WHERE ref='$ref' ORDER BY position ASC");
					if(mysql_num_rows($sql_sub)>0)
						{
						$i=1;
							?><ul>
								<li><?
									while($row_sub=mysql_fetch_array($sql_sub))
										{
											?><a href="<? echo $pre.$row_sub['link']; ?>"><span class="low<? echo $i; ?>"><? echo $row_sub[$lang]; ?></span></a> <?
											$i++;
										}
									?>
								</li>
							</ul><?
						
						}
					
				?>
		</li>			
		<?
		}
		?>
		<span class="menu_end_right"></span>
	</ul>

Barry

Dani AI

Generated

Short answer: you need scripting. As pointed out, pure CSS :hover will hide the submenu the moment the pointer leaves the hovered element, so it cannot reliably provide the “stay open while the user moves across a narrow submenu” behavior you want.

Recommended approach (summary)

  • Toggle a class like open on the top-level li instead of relying on :hover.
  • Use pointerenter/pointerleave (or mouseenter/mouseleave) and a short close timeout (200–350ms) so small pointer slips don’t close the menu.
  • Clear that timeout when the pointer enters the submenu. Close other open items immediately when a new one opens. Because your menu is generated from a database, attach listeners after DOM build or use delegation.

Minimal example (JS)

const menu = document.getElementById('topmenu');
let closeTimer = null;

function closeAll(){ menu.querySelectorAll('li.open').forEach(li => li.classList.remove('open')); }

menu.querySelectorAll(':scope > li').forEach(li => {
  const submenu = li.querySelector('ul');
  li.addEventListener('pointerenter', () => { clearTimeout(closeTimer); closeAll(); li.classList.add('open'); });
  li.addEventListener('pointerleave', () => { closeTimer = setTimeout(() => li.classList.remove('open'), 300); });
  if (submenu) {
    submenu.addEventListener('pointerenter', () => clearTimeout(closeTimer));
    submenu.addEventListener('pointerleave', () => { closeTimer = setTimeout(() => li.classList.remove('open'), 300); });
  }
});

document.addEventListener('pointerdown', e => { if (!menu.contains(e.target)) closeAll(); });

Final tips

  • Improve robustness by expanding the effective hover area with a transparent pseudo-element if the submenu is very narrow.
  • Add keyboard support (focus/blur, aria-expanded) and a touch fallback (tap-to-open).
  • Tune the timeout to taste; 200–300ms usually feels natural.

You can't control the hover with CSS. You'll need some scripting. You could create a hidden div to hold your sub menu and position it off the page. Then when the user hovers you could slide it into position. When the user hovers over another drop down menu you'd slide that one into position and move the other one off the page.

Or you could have a hidden div that you make visible when the user hovers. "onMouseOver".

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.