CSS :hover在移动设备上或其他设备上作为切换使用。

20

我正在做一个简单的 :hover 滑动覆盖,如图所示,它应该滑入一个“收藏文章”的控件,用户可以点击该控件来将此项目标记为收藏。

虽然在桌面上使用鼠标悬停和单击时效果很好,但我不确定它是否可以作为移动设备或其他设备上的有效控件使用(例如,单击以切换,然后再次单击以标记项目为收藏)。

如果我理解正确,至少在iOS(Safari)和Android(Chrome)上,默认浏览器行为是将触摸模拟为hoverclick。但这是一种 标准 吗?例如:

  • Windows Phone 或 Wii U 是否会执行相同的操作?
  • click会在hover之后约300ms触发,因此可能会出现幽灵点击问题吗?

我当然可以在此元素上绑定单击/触摸事件,只是想知道现在是否仅使用 CSS 的 :hover 就足够了。

澄清一下:我不是在问关于:hover支持的问题,这只对指针驱动的环境有意义。我问的是设备是否可以并且应该将可悬停元素处理为用户单击/点击(就像iOS/Android一样)。

输入图像描述


2
我不会依赖于所有设备都支持:hover。任何基于触摸的浏览器都可能以不同的方式实现它,而且在我看来,iOS 处理得相当糟糕。您应该使用 Modernizr 仅在.no-touch设备上绑定:hover事件(这样触摸设备就不会尝试触发自己的:hover状态),然后在.touch设备上单独绑定触摸事件,如果您希望触摸某些元素时触发悬停状态。 - Christian
你是否考虑过在某些情况下(支持或不支持触摸或悬停)使用“特性检测”?可以使用类似于 “ontouchstart” in document.documentElement 的方法。 - Ronni Skansing
@RonniSkansing 特性检测是非常可行的,而且可能是现在的标准例程。但我很好奇,在过去的2-3年中,我们是否已经为非指针设备上的 :hover 处理建立了任何共同的行为。 - bitinn
@bitinn 并不是所有的设备都支持悬停(hover)功能。我们已经建立了常见的方法来优雅地回退处理这些和其他问题。使用modernizr或如上所述,在没有触摸事件的情况下将类添加到悬停元素中。 - Ronni Skansing
5个回答

22

您的问题不是很清晰,我不能确定您是在问“我能在所有设备上使用:hover吗?”还是“:hover在所有设备上表现一样吗?”或者“:hover是网络上的标准元素吗?”

此外,这主要取决于您对“所有设备”的概念,如果您考虑的是目前使用最多的设备还是也包括使用较少的和不常见的设备。

我将引用以下内容,但我相信您已经阅读过了:

交互式用户代理有时会根据用户操作改变渲染。CSS 为常见情况提供了三个伪类:

:hover 伪类应用于用户指定元素(使用某些指针设备),但不激活该元素。例如,当光标(鼠标指针)悬停在元素生成的框上时,视觉用户代理可以应用此伪类。不支持交互式媒体的用户代理不必支持此伪类。一些支持交互式媒体的符合规范的用户代理可能无法支持此伪类(例如,笔设备。当用户激活元素时,:active 伪类适用。例如,在用户按下鼠标按钮和释放它之间。

CSS 不定义哪些元素可能处于上述状态,或这些状态如何进入和退出。脚本可以改变元素是否对用户事件做出反应,而不同的设备和 UA 可能有不同的指向或激活元素的方式

5.11.3 动态伪类::hover、:active 和 :focus http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes

正如您在W3C规范中所看到的,它声称对于非交互式媒体用户代理以及某些交互式媒体用户代理,:hover伪类并不是必需的。因此可以安全地假设:hover并非始终被支持。

要深入探讨这个问题,请阅读以下Safari移动版规格说明:

此外,在iOS上使用Safari的用户直接用手指与您的网页内容交互,而不是使用鼠标。 这为触摸启用的接口创造了新机会,但与悬停状态不兼容。例如,鼠标指针可以悬停在网页元素上并触发事件;多点触摸屏幕上的手指则不能。出于这个原因,在iOS上的Safari中模拟了鼠标事件。因此,仅依赖mousemove、mouseover、mouseout或CSS伪类:hover的元素可能无法在iPad或iPhone等触摸屏幕设备上按预期运行

您可以直接处理触摸,甚至在iOS的Safari中检测高级手势,使用DOM Touch事件touchstart、touchmove、touchend和touchcancel。与被模拟的鼠标事件不同,DOM Touch事件专门设计为与触摸界面一起使用,因此它们的行为是可靠且符合预期的。

5. 为触摸界面做好准备 https://developer.apple.com/library/content/technotes/tn2010/tn2262/_index.html

苹果在这里明确表示,他们倾向于用触摸手势模拟指针,但明确建议避免使用:hover伪类,因为它在他们的触摸设备上的表现不同。

我们可以深入挖掘并获取地球上每个用户代理的所有文档,但是前两个已足以假设以下情况:

  • 非交互式设备不需要支持:hover
  • 交互式设备可以支持伪类(但这并非强制性的,例如屏幕阅读器或点字屏可能会忽略它)
  • 在没有指针的情况下,苹果触摸设备会模拟:hover
  • 可以安全地假定当前触摸设备也会模拟:hover
  • 可以安全地假定任何其他浏览器/设备根据其界面不一定需要支持:hover
  • 最近的浏览器很可能都会支持:hover,因为它是用户的视觉辅助功能。
  • 因此,回答我上面所有问题的答案:

    :hover是Web上的标准元素吗?”

    :hover是W3C的标准元素,事实上它声称必须由指针事件触发,但对于某些接口并不是必需的。

    “我能在所有设备上使用:hover吗?”

    是的,你可能可以。不支持:hover的设备很可能是你的目标用户之外的设备/用户。最好问问自己:“我的产品的最终用户是谁?”如果他们只是移动用户、盲人或喜欢使用任天堂DS浏览的人,则不要使用:hover事件,否则可以使用。

    :hover在所有设备上的行为是否相同?”

    不是的,正如苹果在其设备上所述,它将不会像桌面端那样表现,这可能反映了所有没有指针的设备的相同行为。

    如果您计划通过悬停状态进行用户操作,请不要这样做。这通常是一个不好的做法,无论是在桌面设备还是其他情况下都应该避免使用。悬停并不是一个行动的呼叫,点击才是。悬停不应该被视为“切换”,而更像是用户的视觉辅助工具,帮助他/她理解该元素是否会触发某个操作。

    如果我理解了您的应用程序,那么悬停并不可靠,在您的特定情况下,您应该重新考虑如何使它起作用。使用一种更可靠的方法(并符合您的用户的期望)。


CSS并没有定义哪些元素可以处于上述状态,或者这些状态是如何进入和离开的。脚本可以改变元素是否对用户事件做出反应,不同的设备和UA可能有不同的指向或激活元素的方式。因此,CSS2规范确实声明了不需要明确要求实现,现在的问题是我们是否看到设备制造商之间有共识(或者通过更新的CSS规范来解决这个问题)? - bitinn
1
无论如何,我相信我们已经深入探讨了这个问题,所以向您致敬! - bitinn
我猜测一下。明显,在 CSS 存在之前,悬停状态的概念已经存在了很久(想想游戏菜单),后来桌面浏览器也为同样的事情做出了适应,它仍然是 CSS 中最常用的功能之一。归根结底,你的手指实际上就是一个指针,我认为支持这个过去和未来都会被广泛使用的功能是有意义的。 - MacK

3
当使用鼠标和键盘浏览网页时,将光标悬停在网页元素上是一种常见的操作,但在基于触摸的浏览中却没有类似的行为。本主题演示如何使用 aria-haspopup 文档对象模型(DOM)属性,在 Windows 8 上的 Internet Explorer 10 上模拟触摸设备上的悬停操作。
此行为不适用于 Windows 7 上的 Internet Explorer 10(不支持带有 aria-haspopup 的悬停模拟),也不适用于 Windows 8.1 上的 Internet Explorer 11(具有内置触摸悬停支持)。
在触摸场景中,当用户触摸元素时将应用悬停。但是,轻点一个元素也可以激活元素,例如导航链接。实际上,轻敲是同时完成悬停和激活两个动作。这使得交互式内容隐藏在悬停后对于触摸用户不可访问。交互模型完全不同,没有触摸模拟将光标悬停在页面元素上。

最佳实践是不要使用悬停来隐藏用户可以与之交互的内容。相反,请考虑使用 onclick 事件来切换可见性。


实际上,轻触既是悬停又是激活的一种操作。这使得隐藏在悬停后面的交互内容对于触摸用户来说无法访问。不过,需要注意的是,iOS和Android都能够通过轻触来显示:hover元素,然后再次轻触(点击)以激活控件 - 因此这对于这两种设备来说是可以正常工作的。 - bitinn
我的意思是,当您在:hover区域上同时设置了:hover样式和onclick事件,比如在提交按钮上,用户最终会花费大部分时间来尝试触发按钮的“点击”(300毫秒用于hover轻触,300毫秒用于点击轻触)。 - mohamedrias
特别是对于iOS,width=device-width页面不会自动删除300毫秒。但我的示例有效,因为我们有一个滑入的CSS变换效果,这给用户良好的感知性能。 - bitinn
太好了 :) 我错过了赏金 ;) - mohamedrias

2
我认为这个问题的一部分尚未得到回答,即Windows手机在“悬停”方面的实际行为是什么。为了澄清:
考虑一个为桌面/鼠标使用编写的网页,其中有CSS标记,以便“悬停”更改应用于对象的样式。如果在iPhone或Android上查看该页面并点击该对象,则会发生样式更改(即,它的行为就像对象具有onClick()事件处理程序来更改样式)。Windows Phone会发生同样的事情吗?
我可以回答那个问题,至少对于运行Win 8.1的Nokia Lumia 630:
不会。当您在敲击的初始部分按下手指时,样式更改确实发生了变化,但是当您在敲击结束时释放手指时,样式会恢复原始状态。(尽管这可能是触摸“悬停”的更有效解释,但它是否有任何实际用途是另一回事。)
我想补充说明,iPhone / Safari对悬停的解释也有“关闭”状态。当您点击其他对象时,会触发此状态。
为了展示这一点并允许在不同设备/浏览器上进行测试,我在www.davidleader.net/mobiledemo.html上设置了演示页面。这实现了onClick(),onMouseover()和:hover来更改图像的不透明度,从而显示下面的不同图像。(因此,它依赖于对不透明度的支持,但这已经存在一段时间了。)还有一个“愚蠢的图形”可供单击,以演示iPhone上悬停结束。
总之,在移动设备上解释“悬停”没有正式标准,也没有实际标准。因此,如果您的目标是移动设备,请避免使用“悬停”。

1

目前还没有一个很好地支持移动设备:hover状态的工具。

查看相关问题

我没有在移动设备上使用Modernizr.js,但它可以检测浏览器是否支持触摸事件,因此如果用户使用移动设备,它会在html标签中添加“.touch”类。

所以你可以像这样使用它,例如:

.touch a:active{ /*css code here */ }

希望这能在某种程度上有所帮助。

1
我不是在询问 :hover 支持的问题,这只有在指针驱动的环境中才有意义。我在询问的是设备是否会处理可悬停元素,就像用户点击/轻敲一样(iOS/Android 会)。 - bitinn

0

说到手机,我怀疑是否有任何标准。是的,触摸设备在被触摸时应用悬停状态非常普遍,但您永远无法确定用户可能使用任何数量的浏览器,这些浏览器可能以不同的方式解释悬停状态。

我认为您最好的选择是针对最低公共分母,并假定每个触摸设备只能响应触摸操作。

当然,答案是编写媒体查询和/或JavaScript来强制浏览器按您想要的方式运行。

那只是我的个人哲学,如果有价值的话。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接