支持悬停的设备的媒体查询
Media query for devices supporting hover
我想为支持悬停的浏览器(例如桌面浏览器)和不支持悬停的浏览器(例如触摸屏设备)提供不同的行为。具体来说,我想在支持它的浏览器上声明悬停状态,但不支持不支持它的浏览器,以避免移动浏览器通过额外的点击来模拟它,因为这会破坏页面上的其他交互 - 通过不定义悬停这些浏览器的状态是避免的。
我已经阅读了 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 */
}
}
那么,有没有办法让这项工作按预期的方式进行,还是我走错了路?
来自规格:
none
Indicates that the primary pointing system can’t hover, or there is no pointing system. Examples include touchscreens and screens that use a drawing stylus.
Pointing systems that can hover, but for which doing so is inconvenient and not part of the normal way they are used, also match this value.
For example, a touchscreen where a long press is treated as hovering would match hover: none.
如果您的浏览器(mobile/touch)支持长按模拟悬停,hover: none
的用法将不起作用。您可以做的只是使用默认值并覆盖它(默认 css 优先级):
body {
background: red;
}
@media (hover: hover) {
body {
background: blue;
}
}
桌面将具有 blue
背景,mobile/touch 将具有 red
背景
检查以下示例:
https://jsfiddle.net/mcy60pvt/1/
要检查手机的长按选项,您可以使用此示例:
https://jsfiddle.net/mcy60pvt/3/
在上面的示例中,绿色块对桌面和移动设备都有 :hover
定义,但是对于桌面设备,背景将更改为 yellow
,对于移动设备(长按),背景将更改至 white
.
这是最后一个例子的css:
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;
}
}
在此示例中 - 不支持 :hover
的浏览器将查看带有绿色背景的 hover me 框,而 "hover" (touch/long-press) - 背景将变为白色。
更新
至于添加的伪代码:
.myelement {
/* some styling #1 */
/* note: no hover state here */
}
@media(hover: hover) {
.myelement {
/* some styling that override #1 styling in case this browser suppot the hover*/
}
.myelement:hover {
/* what to do when hover */
}
}
感谢 Dekel 的评论,我通过 运行 JS 中的逻辑并应用 class 解决了这个问题:
例如
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 上对此进行了测试,它按预期工作。
not
应在媒体类型(屏幕、打印、所有等)而不是媒体功能(悬停、点等)前加上前缀。
错误:
@media not (hover: none)
正确:
@media not all and (hover: none)
是的,它不直观而且很奇怪。 Source (see comments).
所以你不需要javascript来替换媒体查询的结果。
根据 ,我们只能解决支持纯 css 和 @media not all and (hover: none)
悬停的设备。看起来很奇怪,但确实有效。
我用它制作了一个 Sass mixin 以便于使用:
@mixin hover-supported {
@media not all and (hover: none) {
&:hover {
@content;
}
}
}
对于支持悬停的设备,以下内容会将 .container
的背景颜色从悬停时的红色更改为蓝色,对于触摸设备则没有变化:
.container {
background-color: red;
@include hover-supported() {
background-color: blue;
}
}
要支持 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)
的组合对于定位移动设备应该更有用,因为移动屏幕变得更大,我们失去了像素尺寸与移动设备与桌面设备之间的相关性(当您希望区分平板电脑时,情况已经如此)和桌面)
您可以使用此 Sass mixin 来设置悬停样式,它将使用推荐的替代品 :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;
}
}
我想为支持悬停的浏览器(例如桌面浏览器)和不支持悬停的浏览器(例如触摸屏设备)提供不同的行为。具体来说,我想在支持它的浏览器上声明悬停状态,但不支持不支持它的浏览器,以避免移动浏览器通过额外的点击来模拟它,因为这会破坏页面上的其他交互 - 通过不定义悬停这些浏览器的状态是避免的。
我已经阅读了 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 */
}
}
那么,有没有办法让这项工作按预期的方式进行,还是我走错了路?
来自规格:
none
Indicates that the primary pointing system can’t hover, or there is no pointing system. Examples include touchscreens and screens that use a drawing stylus.
Pointing systems that can hover, but for which doing so is inconvenient and not part of the normal way they are used, also match this value.For example, a touchscreen where a long press is treated as hovering would match hover: none.
如果您的浏览器(mobile/touch)支持长按模拟悬停,hover: none
的用法将不起作用。您可以做的只是使用默认值并覆盖它(默认 css 优先级):
body {
background: red;
}
@media (hover: hover) {
body {
background: blue;
}
}
桌面将具有 blue
背景,mobile/touch 将具有 red
背景
检查以下示例:
https://jsfiddle.net/mcy60pvt/1/
要检查手机的长按选项,您可以使用此示例:
https://jsfiddle.net/mcy60pvt/3/
在上面的示例中,绿色块对桌面和移动设备都有 :hover
定义,但是对于桌面设备,背景将更改为 yellow
,对于移动设备(长按),背景将更改至 white
.
这是最后一个例子的css:
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;
}
}
在此示例中 - 不支持 :hover
的浏览器将查看带有绿色背景的 hover me 框,而 "hover" (touch/long-press) - 背景将变为白色。
更新
至于添加的伪代码:
.myelement {
/* some styling #1 */
/* note: no hover state here */
}
@media(hover: hover) {
.myelement {
/* some styling that override #1 styling in case this browser suppot the hover*/
}
.myelement:hover {
/* what to do when hover */
}
}
感谢 Dekel 的评论,我通过 运行 JS 中的逻辑并应用 class 解决了这个问题:
例如
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 上对此进行了测试,它按预期工作。
not
应在媒体类型(屏幕、打印、所有等)而不是媒体功能(悬停、点等)前加上前缀。
错误:
@media not (hover: none)
正确:
@media not all and (hover: none)
是的,它不直观而且很奇怪。 Source (see comments).
所以你不需要javascript来替换媒体查询的结果。
根据 @media not all and (hover: none)
悬停的设备。看起来很奇怪,但确实有效。
我用它制作了一个 Sass mixin 以便于使用:
@mixin hover-supported {
@media not all and (hover: none) {
&:hover {
@content;
}
}
}
对于支持悬停的设备,以下内容会将 .container
的背景颜色从悬停时的红色更改为蓝色,对于触摸设备则没有变化:
.container {
background-color: red;
@include hover-supported() {
background-color: blue;
}
}
要支持 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)
的组合对于定位移动设备应该更有用,因为移动屏幕变得更大,我们失去了像素尺寸与移动设备与桌面设备之间的相关性(当您希望区分平板电脑时,情况已经如此)和桌面)
您可以使用此 Sass mixin 来设置悬停样式,它将使用推荐的替代品 :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;
}
}