A shim for the Media Queries Level 4 `hover` @media feature
npm install mq4-hover-shimA shim for the Media Queries Level 4 hover @media feature.
The CSSWG's Media Queries Level 4 Working Draft defines a hover media feature that can be used in media queries. This can be used to determine whether the user-agent's primary pointing device truly supports hovering (like mice do) (the hover value), or emulates hovering (e.g. via a long tap, like most modern touch-based mobile devices) (the on-demand value), or does not support hovering at all (like some old mobile devices) (the none value). This matters because emulated hovering typically has some ugly quirks, such as :hover being "sticky" (i.e. a hovered element stays in the :hover state even after the user stops interacting with it and until the user hovers over a different element). It is often better to avoid :hover styles in browsers where hovering supports is emulated.
However, since it's from a relatively recent Working Draft, the hover media feature is not supported in all current modern browsers or in any legacy browsers. So, this library was created to shim support for the feature into browsers that lack native support for it.
NOTE: This shim only adds support for the hover value of the hover media feature. So you can only tell the difference between "truly supports hovering" (the hover value)" and "does not truly support hovering" (the none or on-demand values).
The shim consists of two parts:
* A PostCSS-based server-side CSS postprocessor that rewrites
``css`
@media (hover: hover) {
some-selector {
property: value;
}
}`
intocss`
some-prefix some-selector {
property: value;
}some-selector
(In normal use-cases, will contain the :hover pseudo-class and some-prefix will be a specially-named CSS class that will typically be added to the element.):hover
* A client-side JavaScript library that detects whether the user-agent truly supports hovering. When the check returns true, then your code can add the special CSS class to the appropriate element to enable styles; for example:`js`
$(document).on('mq4hsChange', function (e) {
$(document.documentElement).toggleClass('some-special-class', e.trueHover);
});:hover
Obviously, this requires JavaScript to be enabled in the browser, and would default to disabling styles when JavaScript is disabled.
[hover-pseudo]: https://developer.mozilla.org/en-US/docs/Web/CSS/:hover
* Via npm: npm install mq4-hover-shimjspm install mq4-hover-shim
* Via jspm:
The browser-side portion of the shim depends on jQuery for firing events.
Pull requests to add support for other browser event libraries would be welcomed.
The following is a summary of the results of testing the library in various browsers. Try out the Live Testcase.
Legend:
* True positive - Browser supports real hovering, and mq4-hover-shim reports that it supports real hovering
* True negative - Browser does NOT support real hovering, and mq4-hover-shim reports that it does NOT support real hovering
* False negative - Browser supports real hovering, and mq4-hover-shim reports that it does NOT support real hovering
* False positive - Browser does NOT supports real hovering, and mq4-hover-shim reports that it supports real hovering
* ??? - This case has yet to be tested.
* Desktop - has a pointing device that supports true hovering (e.g. mouse, trackball, trackpad, joystick, http://xkcd.com/243/); lacks a touch-based pointing input device
* Laplet - has both a pointing device that supports true hovering and a touch-based pointing input device
* Mobile - has a touch-based pointing input device (e.g. touchscreen); lacks a pointing device that supports true hovering
Officially supported:
* Blink (Chrome & recent Opera)
* Desktop - True positive in Chrome >=41; False negative in Chrome <41 due to Chromium bug #441613
* Laplet - ??? (Arguable true negative presumed)
* Mobile (Android) - True negative
* Firefox
* Desktop - True positive
* Laplet - ??? (Arguable true negative presumed)
* Mobile (Android) - True negative
* Android browser
* Mobile (Android 4.0/5.0) - True negative
* Laplet (Android 4.0/5.0) - ??? (Arguable true negative presumed)
* Internet Explorer
* Desktop
* 11 - True positive
* 10 - True positive
* 9 - True positive
* 8 - True positive
* Laplet
* 11 - Arguable true negative
* Mobile (Windows Phone 8.1)
* 11
* in mobile mode - True negative
* in desktop mode - True negative
* Safari (WebKit)
* Desktop (Safari 8 on OS X) - True positive
* Mobile (iOS 8.1) - True negative
Unofficially supported:
* Presto
* Desktop (old Opera 12.1) - True positive
* Mobile (Opera Mini) - ??? (Theoretically: True negative)
* Mobile (Opera Mobile) - ??? (Theoretically: True negative)
* Internet Explorer Mobile <=10 - ??? (Theoretically: True negative)
* Arguments: an options object with one property:
* hoverSelectorPrefix - This string will be prepended to all selectors within @media (hover: hover) {...} blocks within the source CSS.
* Type: string
* Side-effects: none
* Return type: A PostCSS processor object (that was returned from a call to the postcss() function).
* Returns a CSS postprocessor that transforms the source CSS as described above.
* featureDetector - Each of this object's properties is a string filepath to a JavaScript file containing the browser-side feature detector in a particular JavaScript module format.
* es6 - ECMAScript 6 module format (this is the original from which the other versions are generated)
* cjs - CommonJS module format
* umdGlobal - "enhanced" UMD module format; exports a window.mq4HoverShim global if the JS environment has no module system (e.g. if included directly via