Html 如何删除/忽略:在触摸设备上悬停 css 样式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23885255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove/ignore :hover css style on touch devices
提问by Simon Ferndriger
I want to ignore all :hover
CSS declarations if a user visits our website via touch device. Because the :hover
CSS does not make sense, and it can even be disturbing if a tablet triggers it on click/tap because then it might stick until the element loses focus. To be honest, I don't know why touch devices feel the need to trigger :hover
in first place - but this is reality, so this problem is reality as well.
:hover
如果用户通过触摸设备访问我们的网站,我想忽略所有CSS 声明。因为:hover
CSS 没有意义,如果平板电脑在点击/点击时触发它甚至会令人不安,因为它可能会一直粘到元素失去焦点。老实说,我不知道为什么触摸设备首先感觉需要触发:hover
——但这是现实,所以这个问题也是现实。
a:hover {
color:blue;
border-color:green;
// etc. > ignore all at once for touch devices
}
So, (how) can I remove/ignore all CSS :hover
declarations at once (without having to know each one) for touch devices after having them declared?
那么,(如何)我可以:hover
在声明触摸设备后立即删除/忽略所有 CSS声明(而不必了解每一个)?
回答by blade
tl;dr use this: https://jsfiddle.net/57tmy8j3/
TL;博士使用这个:https: //jsfiddle.net/57tmy8j3/
If you're interested why or what other options there are, read on.
如果您对原因或其他选项感兴趣,请继续阅读。
Quick'n'dirty - remove :hover styles using JS
Quick'n'dirty - 使用 JS 删除 :hover 样式
You can remove all the CSS rules containing :hover
using Javascript. This has the advantage of not having to touch CSS and being compatible even with older browsers.
您可以删除包含:hover
using Javascript 的所有 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) {}
}
Limitations: stylesheets must be hosted on the same domain(that means no CDNs). Disables hovers on mixed mouse & touch deviceslike Surface or iPad Pro, which hurts the UX.
限制:样式表必须托管在同一个域中(这意味着没有 CDN)。禁用在Surface 或 iPad Pro等混合鼠标和触摸设备上悬停,这会损害 UX。
CSS-only - use media queries
仅 CSS - 使用媒体查询
Place all your :hover rules in a @media
block:
将所有 :hover 规则放在一个@media
块中:
@media (hover: hover) {
a:hover { color: blue; }
}
or alternatively, override all your hover rules (compatible with older browsers):
或者,覆盖所有悬停规则(与旧浏览器兼容):
a:hover { color: blue; }
@media (hover: none) {
a:hover { color: inherit; }
}
Limitations: works only on iOS 9.0+, Chrome for Android or Android 5.0+ when using WebView. hover: hover
breaks hover effects on older browsers, hover: none
needs overriding all the previously defined CSS rules. Both are incompatible with mixed mouse & touch devices.
限制:使用 WebView 时,仅适用于 iOS 9.0+、Chrome for Android 或 Android 5.0+。hover: hover
打破旧浏览器上的悬停效果,hover: none
需要覆盖所有先前定义的 CSS 规则。两者都与混合鼠标和触摸设备不兼容。
The most robust - detect touch via JS and prepend CSS :hover rules
最强大的 - 通过 JS 检测触摸并添加 CSS :hover 规则
This method needs prepending all the hover rules with body.hasHover
. (or a class name of your choice)
此方法需要在所有悬停规则之前加上body.hasHover
. (或您选择的类名)
body.hasHover a:hover { color: blue; }
The hasHover
class may be added using hasTouch()
from the first example:
的hasHover
类可以使用加入hasTouch()
从第一个例子:
if (!hasTouch()) document.body.className += ' hasHover'
However, this whould have the same drawbacks with mixed touch devices as previous examples, which brings us to the ultimate solution. Enable hover effects whenever a mouse cursor is moved, disable hover effects whenever a touch is detected.
然而,这与之前的例子一样,对于混合触摸设备来说也有同样的缺点,这就给我们带来了最终的解决方案。移动鼠标光标时启用悬停效果,检测到触摸时禁用悬停效果。
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()
This should work basically in any browser and enables/disables hover styles as needed.
这应该基本上适用于任何浏览器,并根据需要启用/禁用悬停样式。
Here's the full example - modern: https://jsfiddle.net/57tmy8j3/
Legacy (for use with old browsers): https://jsfiddle.net/dkz17jc5/19/
这是完整的示例 - 现代:https: //jsfiddle.net/57tmy8j3/
Legacy(用于旧浏览器):https: //jsfiddle.net/dkz17jc5/19/
回答by Jason T Featheringham
Pointer adaptationto the rescue!
指针适应救援!
Since this hasn't been touched in awhile, you can use:
由于这已经有一段时间没有被触及,你可以使用:
a:link {
color: red;
}
a:hover {
color:blue;
}
@media (hover: none) {
a:link {
color: red;
}
}
See this demo in both your desktop browser and your phone browser. Supported by modern touch devices.
在您的桌面浏览器和手机浏览器中查看此演示。由现代触摸设备支持。
Note: Keep in mind that since a Surface PC's primary input (capability) is a mouse, it will end up being a blue link, even if it's a detached (tablet) screen. Browsers will (should) always default to the most precise input's capability.
注意:请记住,由于 Surface PC 的主要输入(功能)是鼠标,因此它最终会成为一个蓝色链接,即使它是一个分离的(平板电脑)屏幕。浏览器将(应该)始终默认为最精确的输入功能。
回答by ProgrammerPer
I have encountered the same problem (in my case with Samsung mobile browsers) and therefore I stumbled upon this question.
我遇到了同样的问题(就我的三星移动浏览器而言),因此我偶然发现了这个问题。
Thanks to Calsal's answerI found something that I believe will exclude virtually all desktop browsers because it seems to be recognized by the mobile browsers I tried (see screenshot from a compiled table: CSS pointer feature detection table ).
感谢Calsal 的回答,我发现了一些我认为几乎可以排除所有桌面浏览器的东西,因为我尝试过的移动浏览器似乎可以识别它(请参阅编译表中的屏幕截图:CSS 指针特征检测表)。
MDN web docsstate that
MDN 网络文档指出
The pointer CSS @media feature can be used to apply styles based on whether the user's primary input mechanism is a pointing device, and if so, how accurate it is
指针 CSS @media 功能可用于根据用户的主要输入机制是否是指点设备来应用样式,如果是,则它的准确程度
.
.
What I discovered is that pointer: coarseis something that is unknown to all desktop browsers in the attached table but known to all mobile browsers in the same table. This seems to be most effective choice because all other pointer keyword values give inconsistent results.
我发现的是指针:粗略是附加表中所有桌面浏览器都不知道的东西,但同一个表中的所有移动浏览器都知道。这似乎是最有效的选择,因为所有其他指针关键字值都会给出不一致的结果。
Hence you could construct a media query like Calsaldescribed but slightly modified. It makes use of a reversed logic to rule out all touch devices.
因此,您可以构建一个类似于Calsal描述但稍作修改的媒体查询。它使用相反的逻辑来排除所有触摸设备。
Sass mixin:
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;
}
}
Compiled CSS:
编译的CSS:
a {
color: green;
border-color: blue;
}
@media not all and (pointer: coarse) {
a:hover {
color: blue;
border-color: green;
}
}
It is also described in this gistI created after researching the problem. Codepenfor empirical research.
我在研究问题后创建的这个要点中也描述了它。 用于实证研究的Codepen。
UPDATE: As of writing this update, 2018-08-23, and pointed out by @DmitriPavlutin this technique no longer seems to work with Firefox desktop.
更新:截至 2018 年 8 月 23 日撰写此更新时,@DmitriPavlutin 指出此技术似乎不再适用于 Firefox 桌面。
回答by Calsal
According to Jason′s answerwe can address only devices that doesn't support hover with pure css media queries. We can also address only devices that support hover, like moogal′s answerin a similar question, with
@media not all and (hover: none)
. It looks weird but it works.
根据Jason 的回答,我们只能解决不支持使用纯 css 媒体查询悬停的设备。我们还可以仅解决支持悬停的设备,例如moogal在类似问题中的回答,使用
@media not all and (hover: none)
. 它看起来很奇怪,但它有效。
I made a Sass mixin out of this for easier use:
为了更容易使用,我做了一个 Sass mixin:
@mixin hover-supported {
@media not all and (hover: none) {
&:hover {
@content;
}
}
}
Update 2019-05-15: I recommend this article from Mediumthat goes through all different devices that we can target with CSS. Basically it's a mix of these media rules, combine them for specific targets:
2019 年 5 月 15 日更新:我推荐这篇来自 Medium 的文章,它涵盖了我们可以使用 CSS 定位的所有不同设备。基本上它是这些媒体规则的混合,将它们结合起来用于特定目标:
@media (hover: hover) {
/* Device that can hover (desktops) */
}
@media (hover: none) {
/* Device that can not hover with ease */
}
@media (pointer: coarse) {
/* Device with limited pointing accuracy (touch) */
}
@media (pointer: fine) {
/* Device with accurate pointing (desktop, stylus-based) */
}
@media (pointer: none) {
/* Device with no pointing */
}
Example for specific targets:
特定目标的示例:
@media (hover: none) and (pointer: coarse) {
/* Smartphones and touchscreens */
}
@media (hover: hover) and (pointer: fine) {
/* Desktops with mouse */
}
I love mixins, this is how I use my hover mixin to only target devices that supports it:
我喜欢 mixin,这就是我如何使用我的悬停 mixin 来只定位支持它的设备:
@mixin on-hover {
@media (hover: hover) and (pointer: fine) {
&:hover {
@content;
}
}
}
button {
@include on-hover {
color: blue;
}
}
回答by Marouen Mhiri
try this:
尝试这个:
@media (hover:<s>on-demand</s>) {
button:hover {
background-color: #color-when-NOT-touch-device;
}
}
UPDATE: unfortunately W3C has removed this property from the specs (https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1).
更新:不幸的是,W3C 已经从规范中删除了这个属性(https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1)。
回答by SeldomNeedy
I'm dealing with a similar problem currently.
我目前正在处理类似的问题。
There are two mainoptions that occur to me immediately: (1) user-string checking, or (2) maintaining separate mobile pages using a different URL and having users choose what's better for them.
我立即想到了两个主要选项:(1) 用户字符串检查,或 (2) 使用不同的 URL 维护单独的移动页面并让用户选择更适合他们的页面。
- If you're able to use an internet duct-tape language such as PHP or Ruby, you can check the user stringof the device requesting a page, and simply serve the same content but with a
<link rel="mobile.css" />
instead of the normal style.
- 如果您能够使用诸如 PHP 或 Ruby 之类的 Internet 管道磁带语言,您可以检查请求页面的设备的用户字符串,并简单地提供相同的内容,但使用 a
<link rel="mobile.css" />
而不是正常样式。
User strings have identifying information about browser, renderer, operating system, etc. It would be up to you to decide what devices are "touch" versus non-touch. You may be able to find this information available somewhere and map it into your system.
用户字符串包含有关浏览器、渲染器、操作系统等的识别信息。由您决定哪些设备是“触摸”设备和非触摸设备。您可以在某处找到此信息并将其映射到您的系统中。
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:
A. 如果允许您忽略旧浏览器,您只需在普通的非移动 css 中添加一条规则,即:EDIT: Erk。在做了一些实验之后,我发现下面的规则除了会导致美学效果被禁用之外,还禁用了跟踪 webkit 浏览器中的链接的能力 - 参见http://jsfiddle.net/3nkcdeao/
因此,你将有在如何修改移动案例规则方面比我在这里展示的更有选择性,但这可能是一个有用的起点:
* {
pointer-events: none !important; /* only use !important if you have to */
}
As a sidenote, disabling pointer-events on a parent and then explicitly enabling them on a child currently causes any hover-effects on the parent to become active again if a child-element enters :hover
.
See http://jsfiddle.net/38Lookhp/5/
作为旁注,在父级上禁用指针事件,然后在子级上显式启用它们当前会导致在子级元素进入时再次激活父级上的任何悬停效果:hover
。
见http://jsfiddle.net/38Lookhp/5/
B. If you're supporting legacy web-renderers, you'll have to do a bit more work along the lines of removing any rules which set special styles during :hover
. To save everyone time, you might just want to build an automated copying + seding command which you run on your standard style sheets to create the mobile versions. That would allow you to just write/update the standard code and scrub away any style-rules which use :hover
for the mobile version of your pages.
B. 如果您支持旧版 Web 渲染器,您将需要做更多的工作来移除在:hover
. 为了节省每个人的时间,您可能只想构建一个自动复制 + sed命令,您可以在标准样式表上运行该命令来创建移动版本。这将允许您只编写/更新标准代码并清除:hover
用于页面移动版本的任何样式规则。
- (I) Alternatively, simply make your users aware that you have an m.website.comfor mobile devices in addition to your website.com. Though subdomaining is the most common way, you could also have some other predictable modification of a given URL to allow mobile users to access the modified pages. At that stage, you would want to be sure they don't have to modify the URL every time they navigate to another part of the site.
- (I) 或者,只需让您的用户知道除了您的website.com之外,您还有一个用于移动设备的m.website.com。虽然子域是最常见的方式,但您也可以对给定 URL 进行一些其他可预测的修改,以允许移动用户访问修改后的页面。在那个阶段,您希望确保他们不必每次导航到站点的其他部分时都修改 URL。
Again here, you may be able to just add an extra rule or two to the stylesheets or be forced to do something slightly more complicated using sedor a similar utility. It would probably be easiest to apply :not to your styling rules like div:not(.disruptive):hover {...
wherein you would add class="disruptive"
to elements doing annoying things for mobile users using js or the server language, instead of munging the CSS.
再次在这里,您可以只在样式表中添加一两个额外的规则,或者被迫使用sed或类似的实用程序来做一些稍微复杂的事情。将 :not 应用到您的样式规则可能是最简单的,例如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 deviceshelpful.
(II) 您实际上可以将前两者结合起来,并且(如果您怀疑用户游移到错误版本的页面)您可以建议他们切换到/切换出移动类型的显示,或者只是在某处放置一个链接允许用户来回翻转。如前所述,@media 查询也可能用于确定用于访问的内容。
(III) 如果您在知道哪些设备是“触摸”的,哪些不是“触摸”设备后准备使用 jQuery 解决方案,您可能会发现CSS 悬停在触摸屏设备上不被忽略很有帮助。
回答by Giacomo Paita
You can use ModernizrJS (see also this StackOverflow answer), or make a custom JS function:
您可以使用ModernizrJS(另请参阅此StackOverflow 答案),或创建自定义 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');
}
to detect the support of touchevent in the browser, and then assign a regular CSS
property, traversing the element with the html.no-touch
class, like this:
以检测触摸的支持,在浏览器中的事件,然后分配一个普通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;
}
回答by mineroot
It was helpful for me: link
这对我有帮助:链接
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");
}
}
}
}
}
}
回答by mr.mii
This is also a possible workaround, but you will have to go through your css and add a .no-touch
class before your hover styles.
这也是一种可能的解决方法,但您必须检查您的 css 并.no-touch
在您的悬停样式之前添加一个类。
Javascript:
Javascript:
if (!("ontouchstart" in document.documentElement)) {
document.documentElement.className += " no-touch";
}
CSS Example:
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>
P.s. But we should remember, there are coming more and more touch-devices to the market, which are also supporting mouse input at the same time.
Ps 但我们应该记住,市场上有越来越多的触摸设备,它们同时也支持鼠标输入。
回答by lars at upstruct
This might not be a perfect solution yet (and it's with jQuery) but maybe it's a direction / concept to work on: what about doing it the other way round? Which means deactivating the :hover css states by default and activate them if a mousemove event is detected anywhere on the document. Of course this does not work if someone deactivated js. What else might speak against doing it this way round?
这可能还不是一个完美的解决方案(它与 jQuery 一起使用)但也许它是一个工作方向/概念:反过来做呢?这意味着默认停用 :hover css 状态,如果在文档的任何位置检测到 mousemove 事件,则激活它们。当然,如果有人停用了 js,这将不起作用。还有什么可能反对这样做呢?
Maybe like this:
也许是这样的:
CSS:
CSS:
/* will only work if html has class "mousedetected" */
html.mousedetected a:hover {
color:blue;
border-color:green;
}
jQuery:
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");
});