javascriptcsshovertouch

How to prevent sticky hover effects for buttons on touch devices


I have created a carousel with a previous and a next button that are always visible. These buttons have a hover state, they turn blue. On touch devices, like iPad, the hover state is sticky, so the button stays blue after tapping it. I don't want that.

What I would prefer is removing the hover state ontouchend. But it doesn't seem like that is possible. Focusing another element doesn't remove the hover state. Tapping another element manually does, but I can't seem to trigger that in JavaScript.

All the solutions I have found seem imperfect. Is there a perfect solution?


Solution

  • Since this part of CSS Media Queries Level 4 has now been widely implemented since 2018, you can use this:

    @media (hover: hover) {
        button:hover {
            background-color: blue;
        }
    }
    

    Or in English: "If the browser supports proper/true/real/non-emulated hovering (e.g. has a mouse-like primary input device), then apply this style when buttons are hovered over."

    For browsers that do not have this implemented (or didn't at the time of this original answer), I wrote a polyfill to deal with this. Using it, you can transform the above futuristic CSS into:

    html.my-true-hover button:hover {
        background-color: blue;
    }
    

    (A variation on the .no-touch technique) And then using some client-side JavaScript from the same polyfill that detects support for hovering, you can toggle the presence of the my-true-hover class accordingly:

    $(document).on('mq4hsChange', function (e) {
        $(document.documentElement).toggleClass('my-true-hover', e.trueHover);
    });