CSS magic, pt. 1: Prevent CSS hover on touch devices
Solving problems within their own domain
JavaScript shouldn’t be the first resort when resolving styling issues in 2018, still we see a lot of it. Perhaps because old habits persist, but they needn’t, because:
Let me give an example.
The problem
I encountered a problem where a responsive web app — intended to behave differently based on device — triggered undesired hover effects when browsing on a mobile device (yes, some mobile browsers support hover).
The Dirty Solution
The most upvoted answer on Stack Overflow directly suggests a “quick’n’dirty” solution using JavaScript. Further down, someone correctly points out that CSS supports pointing device adaptation, and the support is rather overwhelming.
The Clean Solution
So it turns out, we can solve the problem without using another domain by utilizing CSS media queries and the pointer feature. To quote MDN:
The pointer CSS @media media feature can be used to apply styles based on whether the user’s primary input mechanism is a pointing device, and if so, how accurate it is.
Elaborating on one of the suggestions a support table was compiled:
So, it turns out that no desktop browser recognizes pointer: coarse, while all mobile browsers do.
Results
Using reversed logic, a media query can be constructed that prevents a mobile browser from triggering hover effects at all.
HTML
<div>
<!-- Should not trigger on touch device -->
<button>Hover me without touching please</button>
</div>
Sass Mixin
@mixin hover-supported { @media not all and (pointer: coarse) {
&:hover {
@content;
}
}
}button {
background-color:gray; @include hover-supported() {
background-color:white;
}
}
Compiled CSS
button {
background-color: gray;
}@media not all and (pointer: coarse) {
button:hover {
background-color: white;
}
}
Didn’t have to make it more complicated than that.
Update (2018–12–09)
As of 2018–08–23, and pointed out by Matthew Perry in a comment, this technique no longer works with Firefox.
Demo
Try it out here! https://codepen.io/programmerper/pen/XqmWGP. Also described in this gist.