支持悬停的设备的媒体查询

时间:2016-11-10 16:15:17

标签: css hover media-queries touch interaction-media-features

我想为支持悬停的浏览器(例如桌面浏览器)和不支持悬停的浏览器(例如触摸屏设备)提供单独的行为。具体来说,我想在支持它的浏览器上声明悬停状态,但不支持那些不支持浏览器的浏览器,以避免移动浏览器使用额外的点击模拟它,因为这会打破页面上的其他交互 - 通过不定义悬停这些浏览器的状态可以避免。

我已经阅读了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 */
  }
}

那么,有没有办法让这项工作按照预期的方式进行,或者我是否走错了路?

6 个答案:

答案 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)的组合对于定位移动设备将变得更加有用,并且我们失去了像素尺寸与移动设备和台式机之间的相关性(在您希望区分平板电脑和台式机的情况下)