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 >
<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 !!!!
source to share
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
limitsli#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; }
source to share