0

Please look at the code snippet below.

The structure is

<ul>
    <li>text1</li>
    <li> <ul><li> text2 </li>
             <li> text3 </li>
         </ul>
    </li>
</ul>

I have the CSS as follows:

li:hover
{
   background-color: yellow;
}

It works fine for the first li but when I hover over the second item (in the sub-ul), then all items in the sub list are highlighted.

What I need is for a single row to be highlighted at a time, regardless of the relationship of the list item.

I tried

li:child-only:hover

but it did not work. All other answers on S.O. are approaching jQuery to handle this issue. Can this be solved using only CSS?

ul {
  list-style-type: none;
}
li:hover {
  color: blue;
  cursor: pointer;
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<ul>
  <li>Lv1: First Item</li>
  <li>Lv1: Second Item</li>
  <li>
    <ul>
      <li>Lv2: First Item</li>
      <li>
        <ul>
          <li>Lv3: First Item</li>
          <li>Lv3: Second Item</li>
          <li>Lv3: Third Item</li>
        </ul>
      </li>
      <li>Lv2: Second Item</li>
      <li>Lv2: Third Item</li>
    </ul>
  </li>

</ul>
Ahmad
  • 12,336
  • 6
  • 48
  • 88
  • If you want to target ```li``` inside other ```li``` you need to specify the parent in your CSS like ```li li``` for example. Then you can specify behaviour for them. ```li:hover li``` to target the children ```li``` when the main ```li``` is in hover state. – GillesC Mar 23 '15 at 13:01
  • Why not give it a class, something like: `class="sub-li"` – Michelangelo Mar 23 '15 at 13:03

7 Answers7

2

Just change the styles set for li inside ul as you want them to be:

ul {
    list-style-type: none;
    color: black;
    cursor: default;
    background-color: white;
}
li:hover {
    color: blue;
    cursor: pointer;
    background-color: yellow;
}
<ul>
    <li>Lv1: First Item</li>
    <li>Lv1: Second Item</li>
    <li>
        <ul>
            <li>Lv2: First Item</li>
            <li>
                <ul>
                    <li>Lv3: First Item</li>
                    <li>Lv3: Second Item</li>
                    <li>Lv3: Third Item</li>
                </ul>
            </li>
            <li>Lv2: Second Item</li>
            <li>Lv2: Third Item</li>
        </ul>
    </li>
</ul>
ceekay
  • 471
  • 3
  • 14
1

You should put the :hover property on an element surrounding the text content of the li, like so:

ul {
  list-style-type: none;
}
li span:hover {
  color: blue;
  cursor: pointer;
  background-color: yellow;
}
<ul>
  <li><span>Lv1: First Item</span></li>
  <li><span>Lv1: Second Item</span></li>
  <li>
    <ul>
      <li><span>Lv2: First Item</span></li>
      <li>
        <ul>
          <li><span>Lv3: First Item</span></li>
          <li><span>Lv3: Second Item</span></li>
          <li><span>Lv3: Third Item</span></li>
        </ul>
      </li>
      <li><span>Lv2: Second Item</span></li>
      <li><span>Lv2: Third Item</span></li>
    </ul>
  </li>
</ul>

(or maybe use divs if you want to highlight a full row of content)

Martijn Arts
  • 723
  • 7
  • 22
0

ul {
  list-style-type: none;
}
ul li:hover {
  color: blue;
  cursor: pointer;
  background-color: yellow;
}

ul li:hover ul{
  background-color: white;
  color: black;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<ul>
  <li>Lv1: First Item</li>
  <li>Lv1: Second Item</li>
  <li>
    <ul>
      <li>Lv2: First Item</li>
      <li>
        <ul>
          <li>Lv3: First Item</li>
          <li>Lv3: Second Item</li>
          <li>Lv3: Third Item</li>
        </ul>
      </li>
      <li>Lv2: Second Item</li>
      <li>Lv2: Third Item</li>
    </ul>
  </li>

</ul>

U have to reset for other while hovering.

Raja Sekar
  • 2,062
  • 16
  • 23
0

You can override the background color of sub-ul's with the page background color:

ul > li:hover {
  background: yellow;
}
ul > li:hover > ul {
  background: white;
}

Example: http://jsfiddle.net/xo1g3sub/

jion
  • 363
  • 5
  • 16
0

I added few aditional classes so you can actually target the elements you want to style. Here you can find more info about > Is there a CSS selector for the first direct child only?

ul {
  list-style-type: none;
}
.first > li:hover {
  color: blue;
  cursor: pointer;
  background-color: yellow;
}
.first > .nested:hover{
 background:none;
 color:black;
}
<ul class="first">
  <li>Lv1: First Item</li>
  <li>Lv1: Second Item</li>
  <li class="nested">
    <ul>
      <li>Lv2: First Item</li>
      <li>
        <ul>
          <li>Lv3: First Item</li>
          <li>Lv3: Second Item</li>
          <li>Lv3: Third Item</li>
        </ul>
      </li>
      <li>Lv2: Second Item</li>
      <li>Lv2: Third Item</li>
    </ul>
  </li>
</ul>
Community
  • 1
  • 1
dinodsaurus
  • 4,937
  • 4
  • 19
  • 24
0

If you are looking for a very elegant event driven solution, you should implement below code:

Note: It uses e.stopPropagation() to execute event only on hovered element. And this way you add only 2 event listeners that take care of the entire list. No HTML or CSS modifications are necessary.

$('ul').delegate('li', 'mouseover', function (e) {
    if (e.currentTarget.tagName == 'LI') {
        $(e.currentTarget).css('background-color','yellow');
        e.stopPropagation();
    }
});

$('ul').delegate('li', 'mouseout', function (e) {
    if (e.currentTarget.tagName == 'LI') {
        $(e.currentTarget).css('background-color','');
        e.stopPropagation();
    }
});

Working fiddle: https://jsfiddle.net/urahara/t6fp2un2/

Piotr Dajlido
  • 1,982
  • 15
  • 28
0
<ul>
  <li>Lv1: First Item</li>
  <li>Lv1: Second Item</li>
  <li>Lv1: Third Item
    <ul>
      <li>Lv2: First Item</li>
      <li>Lv2: Second Item
        <ul>
          <li>Lv3: First Item</li>
          <li>Lv3: Second Item</li>
          <li>Lv3: Third Item</li>
        </ul>
      </li>
      <li>Lv2: Second Item</li>
      <li>Lv2: Third Item</li>
    </ul>
  </li>

</ul>


ul {
  list-style-type: none;
  position: relative; 
}
ul li:hover {
  color: blue;
  cursor: pointer;
  background-color: yellow;
}
ul > li{    
    display:inline-block;
}
ul li > ul{
    display:none;    
}

ul li > ul li{
    display:block; 
    color:#fff;
}
ul li:hover > ul{
  display: block;
  position: absolute;
  border: 1px solid #000;
  background:blue;  
}
ul li ul{
    position: relative;    
}
ul li ul li ul{    
    position: absolute;
    border: 1px solid #000;
    left: 100%;
}
ul li ul li:hover > ul {
  display: block;

}

Demo

Jakir Hossain
  • 2,457
  • 18
  • 23