3

:hovering on a touch screen can be an accessibility problem (dropdowns) or just muck up design elements (changing colour on a button press and not reverting due to the virtual hover).

So I've resolved to having different behaviour when an element is touched and when it is hovered with the mouse. This is easy enough to implement with Javascript and leveraging mousein and mouseout events, and adding a hover class where appropriate. There are two main problems with this:

  • It's Javascript based which has a number of implications. I wouldn't call not having hover functionality an accessibility issue, as there is a pointer cursor, though.
  • My main problem is that I will have to manually indicate which elements need the classes added outside of my CSS styling. This is extra work, adds an extra area to make mistakes and isn't semantically nice.

So my question is: is there any pure CSS way to detect if and only if the mouse has hovered over an element? One that doesn't respond to touches.

It is not sufficient to detect if a device is touch capable and remove hover functionality from them. Now that many devices have both mouse and touch, this will hinder a perfectly good mouse-enabled experience.

2
  • Something like this? Commented Feb 4, 2015 at 3:33
  • @Ethaan, while that is very cool, the hover selectors still trigger the effect on mobile. Commented Feb 4, 2015 at 18:43

2 Answers 2

3

Solution with CSS only, without Javascript

Use media hover with media pointer will help you resolve this issue:

@media (hover: hover) and (pointer: fine) {
  a:hover { color: red; }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Method 1: Javascript

Why not start with the body having a .no-touch class on it, and then, using JS, detect the device, and remove the class if the device is mobile.

if(//Code to detect mobile)
    $("body").removeClass("no-touch");

Then, in your CSS, code all :hover to be dependent on that parent class.

.no-touch a:hover
{
    text-decoration: underline;
}

This will ensure that the hover styles are enabled by default if JS fails, as well as preventing the otherwise long process of delegating each and every element that you want to disable hover for.


The converse of this would be to add a class if the device is mobile, and then code the CSS to exclude the body that has that class:

body:not(.touch) a:hover
{
    text-decoration: underline;
}

It's not perfect, as it still requires JS, but there is currently not a known purely-css way to detect touch events as opposed to mouse events, at least as I've been able to find through a somewhat extensive Google search.


Method 2: CSS Media Queries

The other option would be to use media queries, but this still leaves a lot to be desired, as devices continue to get better resolution; some tablets can have screen widths equivalent to some old monitors, and unfortunately, old technology dies very slowly.

This has the advantage of being purely CSS, but has its own pitfalls all the same.

You may have someone using an iPad in landscape @ 1024x768 that would be considered a touch device, while an older gentleman is using a desktop on an old 3x2 lcd monitor that has the same resolution: 1024x768

Here's the code though, if you want it:

@media all and (min-width: 1024px)
{
    a:hover
    {
        text-decoration: underline;
    }
}

1 Comment

The Javascript solution there is probably the one I'd go for out of the two, but it still doesn't feel very future proof to me as the definition of mobile is becoming more and more hazy. I think I'd still take JS mouse events and adding classes over these two methods. Really well written and detailed answer, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.