Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS :hover/:focus vs click event on (mobile) touch devices

Often I am in situations where I need to show a menu on hover and for mobile devices menu should open on click. Now e.g. consider following example:

.btn {
  width: 200px;
  background-color: #333;
  color: white;
  padding: 10px;
}
.menu {
  display: none;
  padding: 15px;
}
.btn:hover .menu {
  display: block;
}
.btn:focus .menu {
  display: block;
}
<div class="btn">
  Button
  <div class="menu">I am menu</div>
</div>

Now this automatically works on mobile devices because hover state is sticky on touch devices. But is this hack applicable to all touch devices? That is, is it worth the risk? Would there be some touch device doesn't have hover state sticky? Obviously the alternative is to assign touch/click events with JavaScript on touch devices but this seem redundant because I haven't seen any touch device which don't have sticky hover states?

So my question is:

Is it okay to use the hover state hack or should I use JavaScript events to make it more bullet proof?

like image 758
user31782 Avatar asked Dec 23 '16 14:12

user31782


3 Answers

I'd say it's fine to just stick with the css for most hovers, as long as you're okay with the menu or whatever closing when a user clicks a separate element.

I'm not aware of any mobile browsers that don't adhere to this behavior, at least not major ones. If any of the major browsers dropped this, a huge chunk of the mobile web would need rebuilt.

Probably safe!

like image 95
Octoxan Avatar answered Oct 24 '22 06:10

Octoxan


In my experience, this isn't really a hack but more of a way to imitate hover events with pure CSS. I mainly use the :hover/:focus for these kind of issues, because

1.) They're reliable.

2.) Cheap (in terms of kb).

It takes only 2 rules and no external HTTP request to include a rule for a fully functioning menu, but several lines of JavaScript (or, the horror, jQuery) to create the same thing.

What I said in the comments, you should or could enforce the tabindex attribute to force an element to be focusable, such like:

<div class="non-focusable-clickable-hover-element" tabindex="-1">I cannot be focussed<div>

<div class="focusable-hover-element" tabindex="1">I can be focussed<div>
like image 23
roberrrt-s Avatar answered Oct 24 '22 08:10

roberrrt-s


From my experience this does not work reliably. It may have at one time or another. But it does not with current browsers in 2020.

Better is to use media queries for pointer of type coarse:

@media(hover: none) and (pointer: coarse){
... CSS styling in here ...
}

Medium article on targeting touch devices

This works on all browsers except IE MDN details

like image 25
davidhartman00 Avatar answered Oct 24 '22 06:10

davidhartman00