How to hover with CSS sibling item in nested ordered list only?

This is the HTML structure:

<li>
	<a class="hoverme" href="#">item 1</a>
	<a class=""></a>
	<a class="show-on-hover">
		<img src="">
	</a>
	<ol>
		<li>
			<a href="#" class="hoverme">item 1 nested</a>
			<a class=""></a>
			<a class="show-on-hover"><img src="" width="22"></a>
		</li>
		<li>
			<a href="#" class="hoverme">item 2 nested</a><a></a>
			<a class="show-on-hover"><img src="" width="22">
			</a>
		</li>
	</ol>
</li>

I need to when .hoverme is hover state, then show only the sibling .show-on-hover
Currently I’m using this:

#list .show-on-hover {
  opacity: 0;
  transition: opacity ease-in-out .25s;
}
#list li:hover > a:first-child + a + a {
    opacity: 1;
    transition: opacity ease-in-out .25s;
  }

But if I hover “item 1 nested” or “item 2 nested” it also shows “item1” sibling .show-on-hover and it shouldnt.

1 Like

Hello,
The reason this unexpected behavior occurs is due to the way hover pseudo-class works, when you hover element technically its parent is also hovered & since here the ol element is a child of the outer li element, it also gets hovered
One thing I did try is to move the ol element outside of li & that made it work fine

1 Like

Hello and thanks! Unfortunately at this point I cant change the structure of the list but I’m considering using JS, but wanted to make surer there wasn’t a way with CSS first (least power principle). But I’m not sure how to approach this in JS I’m on it.

1 Like

Is there a reason why? Is there more html that wasnt shared? Just curious because I dont see why an li would be outside of an ol or ul

Sure I explain: it can be done but at this point it would involve changing too much associated code :confused:

I mean I dont how large the code is, but I would say it’s worth to make the change. If theres no other html and the li is truly outside of an ol or ul then thats invalid html, and would be bad practice to work with. As you can see it can also cause styling issue and potential issues down the road depending on what you are doing. Personally, I dont think it makes sense to work with invalid code just because it would take a lot to re work but its your project and your call. I was just curious

1 Like

I see, and thanks I didn’t realize it was invalid o.o … or just bad practice? if is invalid should it not be rendered (at least in css rules are ignored) not sure what happens in HTML but I guess it isn’t ignored… Also I wonder this list is a collapsible tree, if I don’t add child code inside how should I know when to collapse/expand it. I will look into it nevertheless, but code is very large so it might take me a while and yes several scripts depend on this code.

Either you haven’t given us enough of your code to test properly or there are issues with your code. For example, your CSS includes #list in the selector list but I don’t see an element with an id of list in your HTML. So just using the code you provided above isn’t working at all.

Is a simplified version only i will make a codepen

If you look at the li documentation you will see this

Which right now your code violates this. It may still render, but that doesnt make it valid html. Just something to think about

1 Like

That would be a good idea.

Also, another thing to keep in mind here is that showing things on mouse hover only is a bad idea because it excludes everyone who can’t use a mouse. I’m not exactly sure what you are trying to accomplish here, I’ll have to wait to see your codepen, but you should ensure that you can do everything with just the keyboard.

1 Like

Hi I’m trying to better fix the invalid code asap, but yeah I’m still learning JS so…
Ok I apologize because I’m posting a part, but this may be the code that appends wrongly the ol tags

  let li = document.createElement('li')
  li.appendChild(link)
  li.appendChild(link2)
  li.appendChild(link3)
  level = parseInt(level)
  
  if (level == currentListLevel) {
       currentListOl.appendChild(li)
    lastListItem = li
  }

  else if (level > currentListLevel) {
      
    currentListLevel = level
    let ol = document.createElement('ol')
    ol.level = level // store the level in a property
    ol.appendChild(li)
    lastListItem.appendChild(ol)
    currentListOl = ol
    lastListItem = li

  } else if (level < currentListLevel) {

          restaLevel = parseInt(currentListLevel) - parseInt(level)

          function getParentElement(element, levelv2) { 
                while (levelv2 >= 1) {
                  element = element.parentElement.closest('ol');

                  if (!element) return null;
                  levelv2--
                  }

                return element;
            }

                    // cierre experimento
          currentListOl = getParentElement(currentListOl, restaLevel)        
          lastListItem = li
          currentListOl.appendChild(li)
          currentListLevel = level

      }
  
});

give me some time to figure this out…

Update:
Maye with element.parentNode.insertBefore(newElement, element.nextSibling);

This seems to work:

lastListItem.parentNode.appendChild(ol)
    currentListOl = ol
    lastListItem = li

Thank you so much to everyone :heart: , I already fixed all the derived issues from the change, there were fewer than I thought. Now the css line is working properly so I consider this as solved

1 Like

This kept me wondering, so how should I add buttons that appear on a title hover without mouse?

I’m not sure I completely understand what you are trying to do here without seeing it in action. But my first instinct is to say that you shouldn’t be showing buttons on hover at all. If there are buttons that are needed then they should be there at all times. It’s not just keyboard users, touch screen users also don’t really have hovering capabilities.

You could hide the buttons in a toggle/disclosure so that they can be hidden by default and then displayed as needed by clicking on the toggle button. But again, until I can actually see what you are trying to do I’m just guessing here.

1 Like

Thank you, I can explain more, each item in the list basically on hover displays a button on the right of it. If I have them always visible is in my opinion distracting, I’m trying to figure out whats the best approach for mobile users, but I’m not sure yet honestly.

I think it would be better to share a codepen with all code to date. It is still unlear of what your project does, what you want to achieve, and why you are going it in the way you are right now.

There may be some tradeoffs when accessibility is concerned. But would it be more distracting to have that button always showing, or not being able to even access it in the first place?

Well the project is a CSS handbook, but I was told I couldn’t post it here in the future :frowning:
Because yes I wanted to receive feedback, but well…