Reputation: 7413
If you tap on an element on iOS, the browser fires mouseover/mousemove
events and renders :hover
styles. If it detects „content change“ in this process no click event gets fired and you have to tap again to fire a click event. This is documented on developer.apple.com.
I had the issue on a webpage that a „content change“ was detected even though no mouse events or :hover
styles were applied. It took a while, but I was able to reduce the webpage to a small test case:
<style>
a:hover { color: red }
foo + * { color: red }
</style>
<a href="about:blank">foo</a>
<input type="search">
On this page you have to tap two times on the "foo" link to navigate. Tested with iPad mini and iPhone (both native and in the simulator).
After that I found this blog post with a similar issue. But the only fix that works for my issue is the following CSS:
input[type=search]::-webkit-search-cancel-button {
display: none;
}
But I can’t use this workaround if I want the search cancel button to be visible.
Is there an other workaround for this issue?
I posted this bug on bugreport.apple.com several days ago, without a reaction of apple until now. This bug seems to be in iOS 6 and 7 and it would be great if it gets fixed some day.
How do I find out if this is a webkit or an iOS bug?
Where is the right place to report this bug?
This bug seems to be fixed in iOS 8. Tested with iPad mini and iPhone (both native and in the simulator).
Bug wasn’t completely fixed in iOS 8, it still appears if you put some CSS between the braces, e.g. color: red
. I updated the test case to show the bug also in iOS 8.
The bug is not fixed in iOS 9, still no reaction from bugreport.apple.com other than “behaves as intended”.
Upvotes: 19
Views: 11451
Reputation: 376
I faced a similar issue when toggling display state of 2 images upon hover:
.element__color-primary:hover { display: none; }
.element__color-secondary:hover { display: block; }
Android devices worked fine.
Using media queries to apply hover effects only on larger screens was a quick and simple fix that I have implemented. In my case, doing so did not deteriorate user experience.
Upvotes: -1
Reputation:
I'd disable the hover effect for touch devices as a general rule of practice.
The trick is to allow for devices that can have touch but where the touch isn't used to still get the hover effects.
I'd disable all hover effect unless you're using hover effects to create dropdown menus as those actually need the double tab, but for the rest it's quite counterproductive.
What I'm using is a simple script that removes a class on the body whenever a touchstart event occurs.
So I start out with a body that's got a class no-touch
<body class="hoverok">
And then add the following as javascript, to remove that tag on the first touchstart:
(function () {
function antitouch() {
if (!('addEventListener' in window)) {
return;
}
var bodyElement = document.querySelector('body');
function touchStart () {
document.querySelector('body').classList.remove('hoverok');
bodyElement.removeEventListener('touchstart', touchStart);
}
bodyElement.addEventListener('touchstart', touchStart);
}
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', antitouch, false);
} else {
window.attachEvent('onload', antitouch);
}
}());
And then finally change your css selectors to only match if the class touchok is on body.
I've not tested it with your stuff, but it would take away the hover on the a and that should make sure the double tab is never triggered.
eg.:
.hoverok a:hover {
color:red;
}
Upvotes: 4