我想为支持悬停的浏览器(例如桌面浏览器)和不支持悬停的浏览器(例如触摸屏设备)提供单独的行为。具体来说,我想在支持它的浏览器上声明悬停状态,但不支持那些不支持浏览器的浏览器,以避免移动浏览器使用额外的点击模拟它,因为这会打破页面上的其他交互 - 通过不定义悬停这些浏览器的状态可以避免。
我已经阅读了Interaction Media Queries功能,看起来它应该可以解决问题。我可以做类似的事情:
@media (hover: none) {
/* behaviour for touch browsers */
}
根据CanIUse,除了IE11和Firefox之外,我需要支持的所有浏览器都可以使用它。
所以我想知道我是否可以反过来做 - 因为主要的触控设备都支持它,然后否定它:
@media not (hover: none) {
/* behaviour for desktop browsers */
}
然而,这似乎根本不起作用。
我正在尝试做的伪代码示例:
.myelement {
/* some styling */
/* note: no hover state here */
}
@media(this device supports hover) {
.myelement:hover {
/* more styling */
}
}
那么,有没有办法让这项工作按照预期的方式进行,或者我是否走错了路?
答案 0 :(得分:30)
not
应该为媒体类型(屏幕,打印,全部等)添加前缀,而不是媒体功能(悬停,点等)。
错:
@media not (hover: none)
正确:
@media not all and (hover: none)
是的,它不直观且怪异。 Source (see comments)
因此您不需要javascript来替换媒体查询的结果。
答案 1 :(得分:14)
来自规格:
<div class="nav-bar"> Navbar </div>
表示主指向系统无法悬停,或者没有指向系统。示例包括使用绘图笔的触摸屏和屏幕 指向可以悬停的系统,但这样做不方便且不是它们使用的正常方式的一部分,也匹配该值。
例如,长按被视为悬停的触摸屏将匹配hover:none。
如果您的浏览器(移动/触摸)支持长按以模拟悬停,则none
的使用将无效。您可以做的只是使用默认值并覆盖它(使用默认的css优先级):
hover: none
桌面将具有body {
background: red;
}
@media (hover: hover) {
body {
background: blue;
}
}
背景,移动/触摸将具有blue
背景
检查以下示例:
https://jsfiddle.net/mcy60pvt/1/
要检查手机的长按选项,您可以使用此示例:
https://jsfiddle.net/mcy60pvt/3/
在上面的示例中,绿色块具有桌面和移动设备的red
定义,但对于桌面设备,背景将更改为:hover
,而对于移动设备(通过长按),它将更改为{ {1}}。
这是最后一个例子的css:
yellow
在此示例中 - 不支持white
的浏览器将查看带有绿色背景的悬停我框,并且&#34; hover&#34; (触摸/长按) - 背景将变为白色。
关于添加的伪代码:
body {
background: red;
}
div.do-hover {
border: 1px solid black;
width: 250px;
height: 250px;
background: green;
}
div.do-hover:hover {
background: white;
}
@media (hover: hover) {
body {
background: blue;
}
div.do-hover:hover {
background: yellow;
}
}
答案 2 :(得分:7)
感谢Dekel的评论,我通过在JS中运行逻辑并应用类来解决这个问题:
e.g。
const canHover = !(matchMedia('(hover: none)').matches);
if(canHover) {
document.body.classList.add('can-hover');
}
然后在样式表中:
.myElement {
background: blue;
}
.can-hover .myElement:hover {
background: red;
}
我已经在桌面Chrome,Safari和Firefox以及iOS Safari上对此进行了测试,它可以正常运行。
答案 3 :(得分:1)
您可以使用此Sass混合来设置悬停的样式,它将为触摸设备使用推荐的替代:active
。在所有现代浏览器和IE11上均可使用。
/**
Hover styling for all devices and browsers
*/
@mixin hover() {
@media (hover: none) {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
&:active {
@content;
}
}
@media (hover: hover), all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
&:hover {
@content;
}
}
}
.element {
@include hover {
background: red;
}
}
答案 4 :(得分:0)
根据Artin´s answer,我们只能使用@media not all and (hover: none)
来解决支持使用纯css进行悬停的设备。它看起来很奇怪,但它确实有效。
为了方便起见,我制作了一个Sass mixin:
@mixin hover-supported {
@media not all and (hover: none) {
&:hover {
@content;
}
}
}
对于支持悬停的设备,以下内容会在悬停时将.container
的背景颜色从红色变为蓝色,触摸设备无变化:
.container {
background-color: red;
@include hover-supported() {
background-color: blue;
}
}
答案 5 :(得分:0)
要支持Firefox(请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1035774),可能需要两次编写一些规则。请注意,尽管在问题中未指定,但我还是假设这些规则的目的是针对移动屏幕,因此添加了pointer: coarse
:
/* BEGIN devices that DON'T pinch/zoom */
/* If https://bugzilla.mozilla.org/show_bug.cgi?id=1035774
is fixed then we can wrap this section in a ...
@media not all and (pointer: coarse) and (hover: none) {
.. and do away with the 'NEGATE' items below */
.myelement {
/* some styling that you want to be desktop only (style as an anchor on desktop) */
font-size: 14px;
text-decoration: underline;
border: none;
}
/* END devices that DON'T pinch/zoom */
/* BEGIN devices that DO pinch/zoom */
@media (pointer: coarse) and (hover: none) {
.myelement {
/* style as a large button on mobile */
font-size: inherit; /* maintain e.g. larger mobile font size */
text-decoration: none; /* NEGATE */
border: 1px solid grey;
}
.myelement:hover {
/* hover-only styling */
}
}
/* END devices that DO pinch/zoom */
随着移动屏幕变大,(pointer: coarse) and (hover: none)
的组合对于定位移动设备将变得更加有用,并且我们失去了像素尺寸与移动设备和台式机之间的相关性(在您希望区分平板电脑和台式机的情况下)