Media query for devices supporting hover
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.
CSS: How to allow the hover state only on devices which support hover?
I achieved to only hover on devices which have a real hover state with two media queries.
- The first media query makes sure that the CSS is only executed when the current device has a real hover state. This works in nearly every browser: https://caniuse.com/#feat=css-media-interaction
- The second media query is to support IE11 because the first one isn't supported by IE11 https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-ms-high-contrast
@media (hover: hover), (-ms-high-contrast:none) { div:hover { background: red; }}
<div>Hover me!</div>
Does the media query operator not actually work?
According to MDN
if you use the not or only operators, you must explicitly specify a media type.
This snippet adds screen to the media query in your question.
On a laptop without touch screen it appears to work, that is hovering over the div does change it to cyan. If you change the 'coarse' to 'fine' then the hover does not work because the laptop's mouse is considered a fine pointer.
div {
width: 20vmin;
height: 20vmin;
background: pink;
}
@media not screen and (any-pointer: coarse) {
div:hover {
background: cyan;
}
}
<div></div>
Detect if a client device supports :hover and :focus states
The W3C seems to have recognized this problem and has introduced the hover feature:
The hover media feature is used to query the user’s ability to
hover
over elements on the page with the primary pointing device. If a
device has multiple pointing devices, the hover media feature must
reflect the characteristics of the “primary” pointing device, as
determined by the user agent. (To query the capabilities of any
available pointing devices, see the any-hover media feature.)
There is even a media query to check if there is any possibility to hover:
The
any-pointer
andany-hover
media features are identical to the
pointer and hover media features, but they correspond to the union of
capabilities of all the pointing devices available to the user. In the
case of any-pointer, more than one of the values can match, if
different pointing devices have different characteristics.
Code samples:
/* Primary input mechanism system can
hover over elements with ease */
@media (hover: hover) { ... }
/* Primary input mechanism cannot hover
at all or cannot conveniently hover
(e.g., many mobile devices emulate hovering
when the user performs an inconvenient long tap),
or there is no primary pointing input mechanism */
@media (hover: none) { ... }
/* One or more available input mechanism(s)
can hover over elements with ease */
@media (any-hover: hover) { ... }
/* One or more available input mechanism(s) cannot
hover (or there are no pointing input mechanisms) */
@media (any-hover: none) { ... }
Official draft: https://drafts.csswg.org/mediaqueries/#hover
This feature is still at risk, but I really hope it will be fully supported soon as it is already widely supported: https://caniuse.com/#feat=css-media-interaction
Further read: https://css-tricks.com/touch-devices-not-judged-size/
For Chrome test your device here: https://googlechrome.github.io/samples/media-hover-pointer/
Test with JavaScript: https://jsfiddle.net/Blackbam/zkd2cs0t/16/
The best solution for now is most probably to use those media queries with a fallback solution using touch detection via document.createEvent("TouchEvent");
and mouse detection via mousemove.hasMouse
.
How to remove/ignore :hover css style on touch devices
2020 Solution - CSS only - No Javascript
Use media hover with media pointer will help you resolve this issue. Tested on chrome Web and android mobile. I known this old question but I didn't find any solution like this.
@media (hover: hover) and (pointer: fine) {
a:hover { color: red; }
}
<a href="#" >Some Link</a>
How to handle CSS media query negation including browsers which do not support it?
This is a little tricky; since the only way to apply styles for when a browser doesn't support a particular media feature is by taking advantage of the cascade, you'll need to apply the fallback style outside a @media
rule altogether. This does come at a slight cost of duplicating some styles, unfortunately:
.elem { width:200px; height:200px; background-color:#911; margin:20px;}
/* If maximum 300px wide OR the the device is not able to hover */#dude { background-color:#191;}
/* If at least 300px wide and the device is able to hover */@media (min-width: 300px) and (hover: hover) { #carl { background-color:#191; } #dude { background-color:#911; }}
<div id="carl" class="elem"></div><div id="dude" class="elem"></div>
Related Topics
Flexbox VS Tables, Why Do We Need Flexbox
Are All CSS Font-Weight Property's Values Useful
100% Width Bg Images Not Extending on Horizontal Scroll
Is a CSS Property Starting with a Hash (#) Valid
How to Create Inline Pseudo Styles
How to Add Multiple CSS Gradient as a Multiple Background
For What Reason Margin Collapse Rules Were Introduced in CSS
Why Shouldn't I Use Position:Absolute for Positioning Everything
Differencebetween Background-Size: Cover; and Background-Size: 100%;
Transform-Origin for CSS Animation on Svg Working in Chrome, Not Ff
How to Add Different CSS Style to Every Nth Element, Depending on N Using Less
Changing Three.Js Background to Transparent or Other Color