如何删除/忽略:在触摸设备上hoverCSS样式

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

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

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

这个问题有多种解决scheme。

Quick'n'dirty – 删除:使用JShover样式

你可以删除所有包含CSS的规则:hover使用Javascript :hover 。 这样做的优点是不需要触摸CSS,即使是旧版本的浏览器也是如此。

 function hasTouch() { return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; } if (hasTouch()) { // remove all :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) {} } 

限制:样式表必须托pipe在同一个域中 (即没有CDN)。 禁用混合鼠标和触摸设备,如Surface,这会伤害用户体验。

仅限CSS – 使用媒体查询

将所有:hover规则放在@media块中:

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

或者,也可以覆盖所有hover规则(与旧浏览器兼容):

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

限制:使用WebView时,仅适用于iOS 9.0+,Chrome适用于Android或Android 5.0+。 hover: hover在旧版浏览器上hover效果, hover: none重写所有以前定义的CSS规则。 两者都不兼容混合鼠标和触摸设备

最健壮的 – 使用特殊的CSS类和通过JS检测触摸

这个方法需要在body.hasHover之前加上所有的hover规则。 (或者你select的类名)

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

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

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

然而,这与前面的例子中的混合触摸设备有相同的问题,这使我们得到了最终的解决scheme。 每当移动鼠标光标时启用hover效果,只要检测到触摸,就禁用hover效果。

 function watchForHover() { var hasHoverClass = false; var container = document.body; var lastTouchTime = 0; function enableHover() { // filter emulated events coming from touch events if (new Date() - lastTouchTime < 500) return; if (hasHoverClass) return; container.className += ' hasHover'; hasHoverClass = true; } function disableHover() { if (!hasHoverClass) return; container.className = container.className.replace(' hasHover', ''); hasHoverClass = false; } function updateLastTouchTime() { lastTouchTime = new Date(); } document.addEventListener('touchstart', updateLastTouchTime, true); document.addEventListener('touchstart', disableHover, true); document.addEventListener('mousemove', enableHover, true); enableHover(); } watchForHover(); 

这应该基本上在任何浏览器工作,并根据需要启用/禁用hover样式。 试试这里: https : //jsfiddle.net/dkz17jc5/19/

指针适应救援!

由于这一段时间没有被触及,你可以使用:

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

在桌面浏览器和手机浏览器中都可以看到这个演示 。 由现代触摸设备支持。

注意 :请记住,由于Surface PC的主要input(function)是鼠标,因此即使它是分离式(平板)屏幕,它也将成为蓝色链接。 浏览器将(应该)总是默认最精确的input能力。

我正在处理类似的问题。

有两个主要选项立即出现:(1)用户string检查,或(2)使用不同的URL维护单独的移动页面,并让用户select对他们更好的选项。

  1. 如果您能够使用诸如PHP或Ruby之类的互联网pipe道磁带语言,则可以检查请求页面的设备的用户string ,并且仅仅提供相同的内容,但具有<link rel="mobile.css" />而不是正常的风格。

用户string具有关于浏览器,渲染器,操作系统等的标识信息。将由您决定什么设备是“触摸”还是非触摸。 您可能能够在某处find这些信息并将其映射到您的系统中。

答:如果你被允许忽略旧的浏览器 ,你只需要添加一个规则到正常的,非移动的CSS,即: EDIT :Erk。 在做了一些实验之后,我发现下面的规则也禁止跟踪webkit浏览器中的链接,除了导致美观效果被禁用 – 请参阅http://jsfiddle.net/3nkcdeao/
因此,对于如何修改移动案例的规则,您将不得不比我在这里展示的更具select性,但这可能是一个有益的出发点:

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

作为旁注,禁用父指针事件,然后明确地在子对象上启用它们会导致父对象的hover效果在子元素进入时会再次变为活动状态:hover
http://jsfiddle.net/38Lookhp/5/

B.如果你正在支持传统的web渲染器,那么你需要在删除任何设置特殊风格的规则的时候做更多的工作:hover 。 为了节省每个人的时间,你可能只想build立一个自动化复制+ sed ing命令,你可以在标准样式表上运行来创build移动版本。 这将允许您只写/更新标准代码,并删除任何使用:hover样式规则:hover在手机版的页面上。

  1. (I)另外,只要让你的用户知道你有一个移动设备m.website.com除了你的网站 。 虽然子build站是最常见的方式,但您也可以对给定的URL进行其他可预测的修改,以允许移动用户访问修改后的页面。 在这个阶段,你要确保他们不必每次导航到网站的另一部分时修改URL。

再次,在这里,您可能只需要在样式表中添加一两个额外的规则,或者使用sed或类似的实用程序强制执行一些稍微复杂的操作。 这可能是最容易应用的:不是像div:not(.disruptive):hover {...这样的样式规则div:not(.disruptive):hover {...其中你会添加class="disruptive"给使用js或服务器语言的移动用户做恼人的事情,而不是摧毁CSS。

  1. (II)实际上,您可以将前两者结合在一起(如果您怀疑用户已经漫游到错误版本的页面),则可以build议他们切换到移动式显示器,或者只是在某处允许用户来回翻转。 如前所述,@media查询可能也会被用来确定访问的内容。

  2. (三)一旦你知道什么设备是“触摸”,哪些不是,你可能会发现在触摸屏设备上的CSShover不会被忽略 。

你可以使用Modernizr JS(参见这个StackOverflow答案 ),或者创build一个自定义的JS函数:

 function is_touch_device() { return 'ontouchstart' in window // works on most browsers || navigator.maxTouchPoints; // works on IE10/11 and Surface }; if ( is_touch_device() ) { $('html').addClass('touch'); } else { $('html').addClass('no-touch'); } 

在浏览器中检测触摸事件的支持 ,然后分配一个常规的CSS属性,用html.no-touch类遍历元素,如下所示:

 html.touch a { width: 480px; } /* FOR THE DESKTOP, SET THE HOVER STATE */ html.no-touch a:hover { width: auto; color:blue; border-color:green; } 

尝试这个:

 @media (hover:<s>on-demand</s>) { button:hover { background-color: #color-when-NOT-touch-device; } } 

更新:不幸的是,W3C已经从规范中删除了这个属性( https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1 )。

这也是一个可能的解决方法,但是你将不得不通过你的CSS,并在hover样式之前添加一个.no-touch类。

使用Javascript:

 if (!("ontouchstart" in document.documentElement)) { document.documentElement.className += " no-touch"; } 

CSS例子:

 <style> p span { display: none; } .no-touch p:hover span { display: inline; } </style> <p><a href="/">Tap me</a><span>You tapped!</span></p> 

资源

但是我们应该记住,市场上越来越多的触摸设备,同时也支持鼠标input。

这可能不是一个完美的解决scheme(这是与jQuery的),但也许这是一个方向/工作的概念:反过来做什么? 这意味着在默认情况下停用:hoverCSS状态,如果在文档的任何位置检测到鼠标移动事件,则激活它们。 当然,如果有人停用js,这是行不通的。 还有什么可以反对这样做呢?

也许这样:

CSS:

 /* will only work if html has class "mousedetected" */ html.mousedetected a:hover { color:blue; border-color:green; } 

jQuery的:

 /* adds "mousedetected" class to html element if mouse moves (which should never happen on touch-only devices shouldn't it?) */ $("body").mousemove( function() { $("html").addClass("mousedetected"); }); 

这对我有帮助: 链接

 function hoverTouchUnstick() { // Check if the device supports touch events if('ontouchstart' in document.documentElement) { // Loop through each stylesheet for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) { var sheet = document.styleSheets[sheetI]; // Verify if cssRules exists in sheet if(sheet.cssRules) { // Loop through each rule in sheet for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) { var rule = sheet.cssRules[ruleI]; // Verify rule has selector text if(rule.selectorText) { // Replace hover psuedo-class with active psuedo-class rule.selectorText = rule.selectorText.replace(":hover", ":active"); } } } } } } 

这可以通过sass / scss和带有所需断点的媒体查询来解决。

 .myclass { background-color: blue; &:hover { @media screen and (max-width: 320px) { background-color: red; } } } 

根据Jason的回答,我们只能解决不支持使用纯CSS媒体查询hover的设备。 我们也可以只讨论支持hover的设备,比如moogal在类似问题上的回答,而@media not all and (hover: none) 。 它看起来很奇怪,但它的作品。

为了更方便使用,我制作了一个Sass mixin:

 @mixin hover-supported { @media not all and (hover: none) { &:hover { @content; } } } 

以下内容会将.container背景颜色从hover的红色更改为蓝色,以支持支持该设备的设备,并保留为触摸设备的红色:

 .container { background-color: red; @include hover-supported() { background-color: blue; } }