【问题标题】:Media query for devices supporting hover支持悬停的设备的媒体查询
【发布时间】:2017-03-24 18:04:08
【问题描述】:

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

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

那么,有没有办法让这项工作以预期的方式工作,还是我走错了路?

【问题讨论】:

  • 不要使用媒体查询“hover”。我在我的 27" 显示器上使用鼠标,但我所有的浏览器都有设置 "hover:none" 虽然我喜欢并且能够悬停很多。也许我所有的浏览器都有 hover:none 因为我的笔记本电脑在我的外围设备连接有触摸屏。也许你可以试试any-hover媒体查询developer.mozilla.org/en-US/docs/Web/CSS/@media/any-hover
  • @Andreas 将此作为答案,以便它足够突出以被发现。因为这个,我快疯了。每个人都在谈论悬停,我的浏览器都不能通过pointer:fine 检测到我的鼠标,也不能通过hover:hover 接受悬停。但是这个提示正在解决它......
  • 我做了一个网站,你可以参考这个问题andreasburg.de/lenovo-browser-hover-check.html测试你的浏览器的设置
  • 现在至少在 2021 年,您有两个用于 hover 的关键字,如 MDN 文档中的 here 中所述,不确定您是否正在寻找此实现,但希望有人会在未来!
  • @Andreas 您能否将媒体查询“指针”的测试添加到您的测试网站?在 1 个地方对 2 个相关查询进行测试会很方便。

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


【解决方案1】:

not 应作为媒体类型(屏幕、打印、全部等)的前缀,而不是媒体功能(悬停、点等)的前缀。

错误:

@media not (hover: none)

正确:

@media not all and (hover: none)

是的,它不直观且奇怪。 Source (see comments).

因此您不需要 javascript 来替代媒体查询的结果。

【讨论】:

  • 点赞。与上述不同,这无需任何 javascript 即可工作。这确实违反直觉。
  • 绝招!请注意,IE11 似乎完全忽略了此规则。使用另一个特定于 IE 的 hack,它似乎可以工作(尽管它是解决方法的否定版本):@media not all and (hover: none), (-ms-high-contrast: none) {
  • @media (hover: none) 和否定 @media not all and (hover: none) 在 Firefox 中都不做任何事情。该浏览器不支持悬停bugzilla.mozilla.org/show_bug.cgi?id=1035774,但应该没有办法编写not,这样如果not 的主题未定义/无法识别,那么它的计算结果为假(整个媒体查询的计算结果为真) )?
  • not (hover: none) 没有,或者至少不再是错误的。根据 Media Queries 4,这是正确的。令人沮丧的是,任何浏览器都不支持它。见stackoverflow.com/questions/24455958/…
  • 愚蠢的问题,为什么不用@media (hover) {...desktop styles...}
【解决方案2】:

根据规格:

none

表示主定点系统无法悬停,或者没有定点系统。示例包括使用绘图笔的触摸屏和屏幕。
可以悬停但不方便且不属于正常使用方式的指向系统也匹配此值。

例如,长按被视为悬停的触摸屏将匹配 hover: none。

如果您的浏览器(移动/触摸)支持长按模拟悬停,hover: none 的使用将不起作用。您可以做的只是使用默认值并覆盖它(使用默认 css 优先级):

body {
    background: red;
}

@media (hover: hover) {
  body {
    background: blue;
  }
}

桌面将具有blue 背景,移动/触控将具有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 框,而在“悬停”(触摸/长按)时 - 背景将发生变化变白。

更新

至于添加的伪代码:

.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 */
    }
}

【讨论】:

  • 谢谢,但这让我处于同样的情况,即不支持悬停媒体查询的浏览器无法正常运行。
  • 为什么不呢?如果他们不支持 hove 媒体,他们将获得背景 green(除非您在 hover: hover 部分中添加新的背景颜色)。
  • 我会把它添加到答案中,1 分钟
  • 我在问题中添加了一个示例以试图澄清。这个想法是只为支持悬停的浏览器声明悬停状态,这样移动浏览器就不会尝试模拟它。
  • 好的,所以这是一个不同的问题。就像在问“如何在只支持 css3 的浏览器上使用 css4 技巧?” :) 好吧,大多数情况下你不能。如果 Firefox 忽略 hover:hover 定义 - 你真的没有什么可以用它做的(在纯 css 中)。您可以使用 javascript 将类添加到 body 元素并使用基于该类的 css(is-firefox、is-support-hover、is-mobile 等)
【解决方案3】:

感谢 Dekel 的 cmets,我通过在 JS 中运行逻辑并改为应用类解决了这个问题:

例如

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 上进行了测试,它可以正常工作。

【讨论】:

  • 如前所述,js 可以(几乎)总能帮助你:) +1 我的解决方案
  • 非常聪明的答案。好东西
【解决方案4】:

你可以使用这个 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;
    }
}

【讨论】:

  • 这是我找到的最好的解决方案,但仅供参考,它不支持 Firefox 63 及以下版本。
  • @Pluto 感谢您的洞察力。这还不错,这些版本低于 0.1% 的全球使用率。
【解决方案5】:

根据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;
    }
}

【讨论】:

    【解决方案6】:

    要支持 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) 的组合对于定位移动设备应该会变得更有用,因为移动屏幕变得越来越大,并且我们失去了像素尺寸与移动设备与台式机之间的相关性(当您希望区分平板电脑和台式机时已经存在这种情况)

    【讨论】:

    • 这个错误已经在一年前修复了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 2017-05-14
    • 2011-08-11
    • 2014-12-18
    • 2021-05-02
    相关资源
    最近更新 更多