如果用户通过触摸设备访问我们的网站,我想忽略所有:hover CSS声明。因为:hover CSS没有意义,如果平板电脑在点击/点击时触发它,它甚至会令人不安,因为它可能会一直停留到元素失去焦点。说实话,我不知道为什么触屏设备觉得有必要触发:悬停在第一位——但这是现实,所以这个问题也是现实。

a:hover {
  color:blue;
  border-color:green;
  /* etc. > ignore all at once for touch devices */
}

所以,(如何)我可以删除/忽略所有CSS:悬停声明在一次(而不必知道每一个)有他们声明后触摸设备?


当前回答

我也遇到过同样的问题(在我使用三星手机浏览器的情况下),因此我偶然发现了这个问题。

感谢Calsal的回答,我发现了一些东西,我相信它将排除所有桌面浏览器,因为我尝试过的移动浏览器似乎都能识别它(参见编译表的截图:CSS指针特征检测表)。

MDN网络文档说明了这一点

指针CSS @media特性可用于应用基于的样式 用户的主要输入机制是否是指向设备,以及 如果是这样,它有多准确

.

我发现指针:coarse对于附件表中的所有桌面浏览器来说都是未知的,但是对于同一个表中的所有移动浏览器来说却是已知的。这似乎是最有效的选择,因为所有其他指针关键字值给出的结果都不一致。

因此,您可以像Calsal描述的那样构造一个媒体查询,但稍加修改。它使用了一种反向逻辑来排除所有的触摸设备。

Sass混合:

@mixin hover-supported {    
    /* 
     * https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer 
     * coarse: The primary input mechanism includes a pointing device of limited accuracy.
     */
    @media not all and (pointer: coarse) {
        &:hover {
            @content;
        }
    }
}

a {
    color:green;
    border-color:blue;

    @include hover-supported() {
        color:blue;
        border-color:green;
    }
}

CSS编译:

a {
  color: green;
  border-color: blue;
}
@media not all and (pointer: coarse) {
  a:hover {
    color: blue;
    border-color: green;
  }
}

我在研究这个问题后创建的这个要点中也描述了它。 代码依赖于实证研究。

更新(2018): 在撰写此更新时,2018-08-23,并由@DmitriPavlutin指出,这种技术似乎不再适用于Firefox桌面。

更新(2021): 有人向我指出,它似乎在Firefox 87中工作。

其他回答

肮脏的方式…这并不优雅,但却是最简单的方法。

删除任何特征悬停。

.your-class:hover:before {
  color: blue;
  background: linear-gradient(to bottom, rgba(231,56,39,0) 0%, #aaaaaa 100%);
}

@media all and (min-width:320px) and (max-width: 960px) {
    .your-class:hover:before {
    color: black;
    background: transparent;
  }
}

我也遇到过同样的问题(在我使用三星手机浏览器的情况下),因此我偶然发现了这个问题。

感谢Calsal的回答,我发现了一些东西,我相信它将排除所有桌面浏览器,因为我尝试过的移动浏览器似乎都能识别它(参见编译表的截图:CSS指针特征检测表)。

MDN网络文档说明了这一点

指针CSS @media特性可用于应用基于的样式 用户的主要输入机制是否是指向设备,以及 如果是这样,它有多准确

.

我发现指针:coarse对于附件表中的所有桌面浏览器来说都是未知的,但是对于同一个表中的所有移动浏览器来说却是已知的。这似乎是最有效的选择,因为所有其他指针关键字值给出的结果都不一致。

因此,您可以像Calsal描述的那样构造一个媒体查询,但稍加修改。它使用了一种反向逻辑来排除所有的触摸设备。

Sass混合:

@mixin hover-supported {    
    /* 
     * https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer 
     * coarse: The primary input mechanism includes a pointing device of limited accuracy.
     */
    @media not all and (pointer: coarse) {
        &:hover {
            @content;
        }
    }
}

a {
    color:green;
    border-color:blue;

    @include hover-supported() {
        color:blue;
        border-color:green;
    }
}

CSS编译:

a {
  color: green;
  border-color: blue;
}
@media not all and (pointer: coarse) {
  a:hover {
    color: blue;
    border-color: green;
  }
}

我在研究这个问题后创建的这个要点中也描述了它。 代码依赖于实证研究。

更新(2018): 在撰写此更新时,2018-08-23,并由@DmitriPavlutin指出,这种技术似乎不再适用于Firefox桌面。

更新(2021): 有人向我指出,它似乎在Firefox 87中工作。

我目前正在处理一个类似的问题。

我马上想到了两个主要的选择:(1)用户字符串检查,或者(2)使用不同的URL维护单独的移动页面,让用户选择对他们更好的。

如果您能够使用互联网磁带语言(如PHP或Ruby),您可以检查请求页面的设备的用户字符串,并简单地提供相同的内容,但使用<link rel="mobile.css" />而不是常规样式。

用户字符串包含浏览器、渲染器、操作系统等标识信息。你可以决定哪些设备是“触控”的,哪些是非触控的。您可以在某个地方找到这些信息,并将其映射到您的系统中。

A. If you're allowed to ignore old browsers, you just have to add a single rule to the normal, non-mobile css, namely: EDIT: Erk. After doing some experimentation, I discovered the below rule also disables the ability to follow links in webkit-browsers in addition to just causing aesthetic effects to be disabled - see http://jsfiddle.net/3nkcdeao/ As such, you'll have to be a bit more selective as to how you modify rules for the mobile case than what I show here, but it may be a helpful starting point:

* { 
    pointer-events: none !important; /* only use !important if you have to */
}

作为附带说明,在父元素上禁用指针事件,然后在子元素上显式启用它们,当前会导致在父元素上的任何悬停效果在子元素进入:hover时再次激活。 参见http://jsfiddle.net/38Lookhp/5/

B.如果你支持传统的web渲染器,你将不得不做更多的工作,删除任何在:hover期间设置特殊样式的规则。为了节省每个人的时间,你可能只需要在你的标准样式表上运行一个自动复制+ seding命令来创建移动版本。这将允许您只编写/更新标准代码,并删除任何使用:hover用于页面移动版本的样式规则。

(I)或者,简单地让你的用户知道除了你的website.com之外,你还有一个m.website.com用于移动设备。虽然子域名是最常见的方法,但您也可以对给定URL进行其他可预测的修改,以允许移动用户访问修改后的页面。在这个阶段,您希望确保他们不必每次导航到站点的另一部分时都修改URL。

在这里,您可能只需要向样式表添加一两个额外的规则,或者使用sed或类似的实用程序强制执行稍微复杂一些的操作。它可能是最容易应用的:不应用于你的样式规则,如div:not(.disruptive):hover{…其中,你可以添加class="disruptive"到使用js或服务器语言对移动用户做讨厌的事情的元素中,而不是破坏CSS。

(II) You can actually combine the first two and (if you suspect a user has wandered to the wrong version of a page) you can suggest that they switch into/out of the mobile-type display, or simply have a link somewhere which allows users to flop back and forth. As already-stated, @media queries might also be something to look use in determining what's being used to visit. (III) If you're up for a jQuery solution once you know what devices are "touch" and which aren't, you might find CSS hover not being ignored on touch-screen devices helpful.

2020解决方案- CSS只-没有Javascript

使用带有媒体指针的媒体悬停将帮助您解决此问题。在chrome Web和android手机上测试。我知道这个老问题,但我没有找到像这样的答案。

@media (hover: hover) and(指针:fine) { A:悬停{颜色:红色;} } <a href="#" >Some Link</a>

使用这个:https://jsfiddle.net/57tmy8j3/

如果你感兴趣的原因或其他选择,请继续读下去。

快速删除:使用JS的悬停样式

你可以使用Javascript删除所有包含:hover的CSS规则。这样做的优点是不需要接触CSS,甚至与旧的浏览器兼容。

function hasTouch() {
  return 'ontouchstart' in document.documentElement
         || navigator.maxTouchPoints > 0
         || navigator.msMaxTouchPoints > 0;
}

if (hasTouch()) { // remove all the :hover stylesheets
  try { // prevent exception on browsers not supporting DOM styleSheets properly
    for (var si in document.styleSheets) {
      var styleSheet = document.styleSheets[si];
      if (!styleSheet.rules) continue;

      for (var ri = styleSheet.rules.length - 1; ri >= 0; ri--) {
        if (!styleSheet.rules[ri].selectorText) continue;

        if (styleSheet.rules[ri].selectorText.match(':hover')) {
          styleSheet.deleteRule(ri);
        }
      }
    }
  } catch (ex) {}
}

限制:样式表必须托管在同一个域上(这意味着没有cdn)。在Surface或iPad Pro等混合鼠标和触摸设备上禁用悬停,这会损害用户体验。

仅css -使用媒体查询

把你所有的:hover规则放在一个@media块中:

@media (hover: hover) {
  a:hover { color: blue; }
}

或者,重写你所有的悬停规则(与旧浏览器兼容):

a:hover { color: blue; }

@media (hover: none) {
  a:hover { color: inherit; }
}

限制:仅适用于iOS 9.0+, Chrome for Android或Android 5.0+时使用WebView。hover: hover会破坏旧浏览器上的hover效果,hover: none需要覆盖之前定义的所有CSS规则。两者都不兼容混合鼠标和触摸设备。

最健壮的-通过JS和preend CSS检测触摸:悬停规则

这个方法需要在所有悬停规则前加上body.hasHover。(或您选择的类名)

body.hasHover a:hover { color: blue; }

hasHover类可以使用第一个例子中的hasTouch()添加:

if (!hasTouch()) document.body.className += ' hasHover'

然而,这与前面的混合触摸设备有相同的缺点,这将我们带到最终的解决方案。当鼠标光标移动时启用悬停效果,当检测到触摸时禁用悬停效果。

function watchForHover() {
  // lastTouchTime is used for ignoring emulated mousemove events
  let lastTouchTime = 0

  function enableHover() {
    if (new Date() - lastTouchTime < 500) return
    document.body.classList.add('hasHover')
  }

  function disableHover() {
    document.body.classList.remove('hasHover')
  }

  function updateLastTouchTime() {
    lastTouchTime = new Date()
  }

  document.addEventListener('touchstart', updateLastTouchTime, true)
  document.addEventListener('touchstart', disableHover, true)
  document.addEventListener('mousemove', enableHover, true)

  enableHover()
}

watchForHover()

这应该基本上适用于任何浏览器,并根据需要启用/禁用悬停样式。

这里是完整的例子——modern: https://jsfiddle.net/57tmy8j3/ 遗留(用于旧浏览器):https://jsfiddle.net/dkz17jc5/19/