I am new to HTML and CSS and am currently having 2 problems with an icon that is displayed when the mouse hovers over a menu item.

Problem 1
I want the icon to appear to the left of the menu item, but can only get it to display on top of the first letter if the menu item (not say 5px to the left of).

Problem 2
When the mouse hovers over one of the submenu items the icon appears for both the submenu item and its parent - I only want it to display for the submenu item.

Code extracts below. Any help much appreciated.

HTML

<div id="menu">
<ul>
<li id="menu_1">
<a href="Aboutus.html">About Us
<ul id="about_sub">
<li><a href="Who.html">Who We Are</a></li>
<li><a href="What.html">What We Do</a></li>
</ul>
</a>
</li>

<li id="menu_2">
<a href="Services.html">Services
<ul id="services_sub">
<li><a href="Service1.html">Service 1</a></li>
<li><a href="Service2.html">Service 2</a></li>
<li><a href="Service2.html">Service 3</a></li>
</ul>
</a>
</li>

<li id="menu_3">
<a href="Contact.html">Contact Us</a>
</li>
</ul>
</div>


CSS

#menu ul {
position: absolute;
list-style: none;
top:150px;
left: 25px;
width: 120px;
padding: 0px;
margin: 0px;
text-align: left;
font-size: 12px;
font-weight: bold;
}

#menu li {
margin-top: 5px;
}

#menu ul li:hover {
background: url(Images/Menu.bmp) no-repeat;
}

#menu li ul {
position: relative;
top: 0px;
left: 5px;
margin-top: 0px;
font-size: 11px;
font-weight: bold;
}

Dani AI

Generated

Two likely causes and a concise, practical fix.

When a hover style is attached to an LI the browser treats the whole LI (including its child nodes) as hovered. That explains why a submenu hover also lights up the parent. Also, having the submenu placed inside the parent link keeps the pointer "inside" that parent anchor; moving the submenu out of the top-level <a> removes that coupling. See the spec notes on the anchor element and the hover pseudo-class for details: MDN a element and MDN :hover.

A clean, modern solution is to:

  • close the top-level a before the nested ul so the submenu is not inside the parent link, and
  • attach the icon to the link itself (or to a ::before pseudo-element) rather than to the LI. That prevents the parent from showing the icon when a child is hovered.

Example (minimal):

<li>
  <a href="Aboutus.html">About Us</a>
  <ul> ...submenu items... </ul>
</li>

#menu a { display:block; position:relative; padding-left:26px; }
#menu a::before {
  content:"";
  position:absolute;
  left:6px; top:50%;
  width:16px;height:16px;
  background:url(icon.png) no-repeat center;
  transform:translateY(-50%);
  opacity:0; transition:opacity .12s;
}
#menu a:hover::before { opacity:1; }

Using ::before avoids fiddling with negative background positions and keeps the image visually left of the text. Reference: MDN ::before.

Quick troubleshooting: inspect the computed box model to confirm the link is display:block and the left padding equals the icon area. If supporting very old browsers, provide a fallback (background on a instead of ::before). Both and pointed toward spacing and per-row backgrounds — those ideas are valid; the markup/selector change above keeps the behavior predictable and semantic.

Recommended Answers

All 2 Replies

Give the li a href of the menu some padding (equal to the width of the icon) to push it in a bit from where the icon will appear.

An alternate method would be to do it this way:

#MenuDiv {
	position: absolute;
	top:150px;
	left: 25px;
	width: 120px;
}

#MenuTable {
	table-layout: width: 120px, padding: 0px, margin: 0px;
}

.menuTopRow {
	text-indent: 20px;
	font-size: 12px;
	font-weight: bold;
}
.menuTopRow:hover {
	background: url(test.png) no-repeat;
}
.menuSubRow {
	text-indent: 20px;
	padding-left: 5px;
	font-size: 11px;
	font-weight: bold;
}
.menuSubRow:hover {
	background: url(test.png) no-repeat;
	background-position: 5px;
}

Then the following in the HTML:

<div id="MenuDiv">
<table id="MenuTable">
  <tr>
    <td class="menuTopRow"><a href="Aboutus.html">About Us</a></td>
  </tr>
  <tr>
    <td class="menuSubRow"><a href="Who.html">Who We Are</a></td>
  </tr>
  <tr>
    <td class="menuSubRow"><a href="What.html">What We Do</a></td>
  </tr>
  <tr>
    <td class="menuTopRow"><a href="Services.html">Services</a></td>
  </tr>
  <tr>
    <td class="menuSubRow"><a href="Service1.html">Service 1</a></td>
  </tr>
  <tr>
    <td class="menuSubRow"><a href="Service2.html">Service 2</a></td>
  </tr>
  <tr>
    <td class="menuSubRow"><a href="Service3.html">Service 3</a></td>
  </tr>
  <tr>
    <td class="menuTopRow"><a href="Contact.html">Contact Us</a></td>
  </tr>
</table>
</div>

In my example I pushed the text-indent by 20px because the image I was using was 20x20px in size for the hover.

With this method, as the background is being called on specific cell hovers instead of generally between both list and sublist hovers it only triggers the image over the selected line and not the line plus it's parent.

Mark as solved if this fixes your issue :)

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.