Css hover + click / tap strange behavior on touch devices

I know the name is too general. I couldn't find a specific title.

Here is an example https://jsfiddle.net/Exlord/1soagsL5/

Html

<ul>
  <li>item1</li>
  <li>item1</li>
  <li>item with submenu &gt;
    <ul>
      <li>item1</li>
      <li>item1</li>
    </ul>
  </li>
  <li>item1</li>
  <li id='clickable'>item1</li>
</ul>

      

JavaScript

var el = document.getElementById('clickable');
el.addEventListener('click', function(e) {
  console.log(e.target);
}, false);

      

CSS

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 200px;
  max-width: 100%;
}

li {
  background: gray;
  padding: 5px;
  border: solid 1px black;
  position: relative;
}

li:hover > ul {
  display: block;
}

@media all and (min-width: 481px) {
  ul ul {
    display: none;
    position: absolute;
    left: 100%;
    top: 0;
  }
}

@media all and (max-width: 480px) {
  ul ul {
    display: none;
  }
}

      

Try it, it's very simple menu, move the middle element from the submenu, the submenu will be shown in a simple easy the CSS :hover

.

Click on the last item, it has a click event, it will fire correctly.

Now open this in Chrome Touch Modem Mobile Modem.

Click / tap a submenu item, the submenu will open inside the parent item. This is expected behavior.

Now click / tap the last item. The click event will not fire.

How can I fix this with CSS only hover

?

UPDATE: As far as I can tell, the problem is that on the first touch, the last hovering element ( li

with the submenu) remains stationary, and the submenu is ul

hidden, and the height of the parent ul

decreases, and the li

one that was under the tangent point moves upwards, so it no longer is under the tangent point and doesn't get click / touch !!!!

+3


source to share


1 answer


I think you yourself figured out this reason. It seems like the click target is removed before the event reaches the element.

The simplest solution I see is to use some additional Javascript to open and close the submenu on clicks. You are using Javascript for the event anyway #clickable

, so it won't be harmful anymore as long as you save :hover

for cases where Javascript isn't loading.




Original Answer

Touch devices do not have a freeze state due to the hardware interface. Browser manufacturers have chosen a compromise to allow sites that rely on this. Whenever a hover event / style is defined for an element, the first click will trigger that effect instead of clicking. The second faucet should, at least in most cases, fire the original click event.

In your particular case, you have no ul

limits li#clickable

but :hover

is still detected and the browser behaves the way it was designed. Excluding your #clickable

from freezing this will theoretically fix it (I can't test it myself this time).

li:not(#clickable):hover > ul {
  display: block;
}

      

0


source







All Articles