Media request for devices that support freezing

I would like to provide separate behavior for browsers that support freezing (e.g. desktop browsers), as well as those that don't work (e.g. touch devices). In particular, I want to declare a freeze state in browsers that support it, but not for browsers that don’t, in order to avoid mobile browsers emulating it with additional taps, as this disrupts other interactions on the page - without defining Freezing for these browsers can be avoided.

I read into the Interaction Media Queries function , and it looks like this should do the trick. I could do something like:

@media (hover: none) { /* behaviour for touch browsers */ } 

According to CanIUse, it is available in all browsers that I need to support, except for IE11 and Firefox.

So, I thought if I could do it the other way around - since the main touch devices support it and then deny it:

 @media not (hover: none) { /* behaviour for desktop browsers */ } 

However, this does not work at all.

An example of the pseudocode of what I'm trying to do:

 .myelement { /* some styling */ /* note: no hover state here */ } @media(this device supports hover) { .myelement:hover { /* more styling */ } } 

So, is there a way to make this work this way, or am I wrong?

+26
css media-queries touch hover interaction-media-features
Nov 10 '16 at 16:15
source share
6 answers

Thanks to Dekel's comments, I solved this by following the logic in JS and applying the class instead:

eg.

 const canHover = !(matchMedia('(hover: none)').matches); if(canHover) { document.body.classList.add('can-hover'); } 

Then in the stylesheet:

 .myElement { background: blue; } .can-hover .myElement:hover { background: red; } 

I tested this on Chrome, Safari, and Firefox desktops, as well as on iOS Safari, and it works as expected.

+7
Nov 11 '16 at 10:18
source share

not should the media type prefix (screen, print, everything, etc.), and not the media (guidance, dot, etc.).

Wrong:

 @media not (hover: none) 

Right:

 @media not all and (hover: none) 

Yes, its unintuitive and strange. Source (see comments) .

Thus, you do not need javascript for an alternative media query result.

+35
Feb 21 '17 at 9:16
source share

From the specifications:

none

Indicates that the main pointer system cannot be pointed, or there is no pointer system. Examples include touch screens and screens that use a stylus for drawing.
Indicative systems that may hang, but for which it is inconvenient, and are not part of the usual way of using them, also correspond to this value.

For example, a touch screen in which a long press is treated as a hang will correspond to a hang: none.

If your browser (mobile / touch) supports long presses to simulate hovering, using hover: none will not work. You can simply use the default value and override it (with default priority css):

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

The desktop will have a blue background, and for mobile / touch there will be a red background

Check out the following example:
https://jsfiddle.net/mcy60pvt/1/

To test the possibility of a long press on a mobile phone, you can use this example:
https://jsfiddle.net/mcy60pvt/3/

In the above example, the green block has the definition :hover for the desktop and mobile device, however, for the desktop, the background will change to yellow , and for mobile devices (with a long press) it will change to white .

Here is the css example for the last example:

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

In this example, browsers that do not support :hover will view the hover me window with a green background, and during the "hover" (touch / long press), the background will change to white.

Update

Regarding the added pseudocode:

 .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 */ } } 
+14
Nov 10 '16 at 16:49
source share

According to Artin’s answer, we can only access devices that support hovering with pure css, with @media not all and (hover: none) . It looks weird, but it works.

I made a mixture of Sass from it to simplify use:

 @mixin hover-supported { @media not all and (hover: none) { &:hover { @content; } } } 

Below, the background color of the .container will change from red to blue when hovering on devices that support hovering, without changes for touch devices:

 .container { background-color: red; @include hover-supported() { background-color: blue; } } 
0
Aug 22 '17 at 14:29
source share

To support Firefox (see https://bugzilla.mozilla.org/show_bug.cgi?id=1035774 ) you need to write some rules twice. Please note, although in the question I did not indicate pointer: coarse if we assume that the purpose of these rules is to target mobile screens:

 /* 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 eg larger mobile font size */ text-decoration: none; /* NEGATE */ border: 1px solid grey; } .myelement:hover { /* hover-only styling */ } } /* END devices that DO pinch/zoom */ 

The combination of (pointer: coarse) and (hover: none) should become more useful for targeted mobile devices, as mobile screens become larger, and we lose the correlation between pixel sizes and between mobile and desktop computers (even when you want to distinguish between tablet and desktop)

0
Jan 11 '19 at 13:48
source share

You can use this Sass mixin to style your hover; it will use the recommended replacement :active for touch devices. Works in all modern browsers and 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; } } 
0
Sep 05 '19 at 10:35
source share



All Articles