Media query for devices supporting hover

media (hover)
media query for touch devices
css hover
disable hover on mobile
simulate hover on touch devices
caniuse
css touch
css detect mobile

I'd like to provide separate behaviour for browsers supporting hover (e.g. desktop browsers) and ones which don't (e.g. touchscreen devices). Specifically I want to declare a hover state on browsers that support it, but not for browsers that don't, so as to avoid having mobile browsers emulate it with extra taps, as this breaks other interactions on the page - by not defining a hover state for those browsers this is avoided.

I've read up on the Interaction Media Queries feature and it looks like it should do the trick. I'd be able to do something like:

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

According to CanIUse it is available on all the browsers I need to support except IE11 and Firefox.

So I wondered if I could do it the other way around - since the main touch devices all support it, then negate it:

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

However, this doesn't seem to work at all.

Pseudocode example 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 in the way intended, or am I down the wrong track?


not should prefix media type (screen, print, all, etc) and not media feature (hover, point, etc).

Wrong:

@media not (hover: none)

Correct:

@media not all and (hover: none)

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

So you do not need javascript to alternate result of media query.

hover, The definition of 'hover' in that specification. Candidate Recommendation, Initial definition. Browser compatibility. If you want to get rid of hover states on touch devices you can use the hover CSS media feature. @media (hover: hover) {a:hover {background: red; color: white;}} Personally, the hover styles are not bothering very much, but I could imagine that it annoys some people. Using this media query, you can get rid of the sticky hover state. 🎉


From the specs:

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.

If your browser (mobile/touch) support long-press to simulate hover, the usage of hover: none will not work. What you can do is just use a default value and override it (with default css precedence):

body {
    background: red;
}

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

Desktop will have blue background and mobile/touch will have red background

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

To check the long-press option of the mobile you can use this example: https://jsfiddle.net/mcy60pvt/3/

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

Here is the css 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 don't support :hover will view the hover me box with green background, and while "hover" (touch/long-press) - the background will change to white.

update

As for the added pseudo code:

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

Touch Devices Should Not Be Judged By Their Size, If a device has multiple input mechanisms, the pointer media feature must The hover media feature is used to query the user's ability to hover over elements on the page. I hear you shouting: what about browser support? As an excellent initiative, the W3C added Interaction Media Features as a candidate recommendation for L4 Media Queries, which we can use to distinguish touchscreen devices. The four media queries


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

e.g.

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've tested this on desktop Chrome, Safari and Firefox, and iOS Safari and it works as expected.

Introducing CSS Interaction Media Queries - Ross Bulat, CSS media queries give us the means of testing device properties, and to style the @media now supports pointer and hover features:. The hover CSS media feature can be used to test whether the user's primary input mechanism can hover over elements. Syntax. The hover feature is specified as a keyword value chosen from the list below. none


You can use this Sass mixin to style the hover, it will use the recommended substitute :active for touch devices. Works on 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;
    }
}

The hover media query can help to remove hover styles on touch , The CSS media query hover can help to avoid staying hover styles query to detect if the user agent has a hover supporting mechanism. But hey 🤷‍♂️. If you use your mobile device to browse the web regularly, you might  Media Queries Support. CSS Media queries are supported in Internet Explorer (IE) 9+, Firefox 3.5+, Safari 3+, Opera 7+, as well as on smartphones and other screen-based devices. Although older versions of IE don’t support media queries, still there is a way you can make it work.


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

I made a Sass mixin out of this for easier use:

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

The following would change background-color of .container from red to blue on hover for devices that support hover, no change for touch devices:

.container {
    background-color: red;

    @include hover-supported() {
        background-color: blue;
    }
}

Detecting Hover and Touch in CSS and JS - DEV, Detection of non-hover-devices: @media (hover: none) { //Insert Styles for Non-​Hover-Devices }. For IE11-support, extend the media-query with  Using CSS media queries is the most widely adapted solution in the WordPress community if you want to make sure your website is responsive. In this guide, you will learn what responsive design is, how it works, how to use CSS media queries correctly, and what to do if your queries are not working.


Media Queries: interaction media features, Allows a media query to be set based on the presence and accuracy of the user's pointing device, and whether they have the ability to hover over elements on  We do this by adding one more media query (at 600px), and a set of new classes for devices larger than 600px (but smaller than 768px): Example Note that the two sets of classes are almost identical, the only difference is the name ( col- and col-s- ):


@media.hover - CSS, Initial definition. Browser compatibilityUpdate compatibility data on GitHub. Desktop. Chrome, Edge, Firefox, Internet Explorer  Media features provide more specific details to media queries, by allowing to test for a specific feature of the user agent or display device. For example, you can apply styles to only those screens that are greater, or smaller, than a certain width.


CSS: Support hover only on non-touch devices using media query , a:hover {. color: blue;. } } HoverSupported.scss. @mixin hover-supported {. /*. * https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer. * coarse:  The hover media feature is used to query the user’s ability to hover over elements on the page. If a device has multiple input mechanisms, the hover media feature must reflect the characteristics of the “primary” input mechanism, as determined by the user agent.”. – W3C.