Reputation: 142
I have a fiddle here http://jsfiddle.net/13v2fcjf/ It has a basic html document with lists and sublists
<ul>
<li>Item 1
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
</ul>
And I'm using the following css -
li:hover {
background: #f7f7f7;
}
When I hover on an li item with a subitem(s), all the subitems also get highlighted. This is not desirable. I want only the list item on which the user's hovering to be highlighted. How can I achieve this ?
Also, I tried using the :not
selector but it doesn't work.
Upvotes: 1
Views: 2790
Reputation: 35670
This was a challenge, but the following CSS works with your existing markup. It highlights only a hovered li
, without highlighting its parent.
The main trick is to have the CSS create new content when hovering over a nested li
. You can do this using the :before
pseudo element:
li li:hover:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0; left: 0;
z-index: -1;
background: white;
}
(If you're targeting CSS3 browsers only, you can use ::before
instead of :before
.)
This causes a nested li
to cover up its parent li
. The negative z-index prevents the background from covering up any text.
Parent li
's need relative positioning with a z-index, and nested li
's need static positioning for this to work:
li {
position: relative;
z-index: 0;
}
li li {
position: static;
}
The other trick has been mentioned in other posts:
li:hover ul {
background: white;
}
Full CSS:
li {
line-height: 1.65em;
cursor: pointer;
}
li {
position: relative;
z-index: 0;
}
li li {
position: static;
}
li:hover {
background: #def;
}
li:hover ul {
background: white;
}
li li:hover:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0; left: 0;
z-index: -1;
background: white;
}
Upvotes: 0
Reputation: 11056
I think you just need to set the background
on the nested <ul>
tag. Something like this:
li:hover > ul {
background: #fff;
}
Edit: this is assuming you only want the parent <li>
highlighted, which as @j08691 points out in the comments, might not be entirely what you're after. If you want each <li>
to be highlighted, you might have to modify your HTML slightly to make this easier:
<ul>
<li><a>Item 1</a>
<ul>
<li><a>Sub Item 1</a></li>
<li><a>Sub Item 2</a></li>
<li><a>Sub Item 3</a></li>
</ul>
</li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a>
<ul>
<li><a>Child 1</a></li>
<li><a>Child 2</a></li>
<li><a>Child 3</a></li>
</ul>
</li>
</ul>
By wrapping the items and sub-items in another tag - here I've just used an <a>
tag for the sake of argument - you can target that tag to be highlighted on :hover
without the nested tags being affected in the same way as in your original code:
a {
display: inline-block;
padding: 4px;
}
a:hover {
background: #f7f7f7;
cursor: pointer;
}
See http://jsfiddle.net/13v2fcjf/3/
Upvotes: 1
Reputation: 3638
This effect is just natural because the sub items are inside of the main items.
There are two options that come to my mind:
1.) Resetting the background color of the sub lists with
li:hover > ul {
background-color: white;
}
2.) Using the li
items as a container:
<li><span class="highlighted">Item</span></li>
.highlighted:hover {
background-color: red;
}
Upvotes: 0
Reputation: 14927
If Ian's option doesn't work for you, a second opotion is to wrap the <li>
contents in a span and apply the hover to that, like this example fiddle:
HTML:
<ul>
<li><span>Item 1</span>
<ul>
<li><span>Sub Item 1</span></li>
<li><span>Sub Item 2</span></li>
<li><span>Sub Item 3</span></li>
</ul>
</li>
....
CSS
li span:hover {
background: #f7f7f7;
cursor: pointer;
}
HTH, -Ted
Upvotes: 0