web-platform-tests / interop

web-platform-tests Interop project
https://wpt.fyi/interop
311 stars 28 forks source link

A new `:hover-only` pseudo class #839

Open nmn opened 1 week ago

nmn commented 1 week ago

Description

Hover is inherently a feature that only makes sense with a "floating" cursor such as with a mouse or with a floating stylus (like Apple Pencil on iPad pro M2 or later, or some Android Tablets).

However, in order to support legacy usages of :hover touch devices also trigger :hover on the first tap of an element. In modern websites with are optimised for touch this can be very undesirable. Not only does it make all buttons/links with hover styles not work on the first click, the hover styles also get "stuck" after the first tap.

Existing mechanisms to detect real hover is also lacking as it doesn't account for devices that may have both mouse pointers and touch. All of this means that we're forced to use Javascript to detect something as fundamental as hover state.

This article explains this problem further: https://react-spectrum.adobe.com/blog/building-a-button-part-2.html


All we want is a way to apply :hover styles that do not apply on touch. We can get there is a few ways, all of which would be acceptable. Here are some possible paths that I can see:

  1. Add a new :hover-only pseudo class (or :visual-hover or something else) that does not trigger on touch-screens.
  2. Don't trigger :hover styles on any element with touch-action: manipulation. This same style is already used to remove the delay after a tap before a click event is triggered.
  3. Some <meta> tag that disables :hover on touch for a whole page.

This is a HUGE pain point and, at least externally, feels like something that should be easy to fix. Let's please prioritise this.

Rationale

All we want is a way to apply :hover styles that do not apply on touch.

Investigation Roadmap

No response

chriskirknielsen commented 1 week ago

Is this not (mostly?) solved with the @media (hover: hover) media query?

nmn commented 1 week ago

Is this not (mostly?) solved with the @media (hover: hover) media query?

Not at all. @media (hover: hover) resolves to true the entire time on a device that supports both touch and mouse. This includes many Windows PCs, iPads attached to a mouse and Android tablets attached to a mouse.

The media query does not help us detect if the current ":hover" was caused by touch or mouse.

Further, due to multi-touch a boolean value cannot solve this problem even if the media query worked as expected. You could be using the mouse and touch on the screen at the same time.

chriskirknielsen commented 1 week ago

Ah, pardon my ignorance — good points and good to know!