Detect a touch device with only CSS

New standards developments in CSS are providing a better future for developers that needs to detect touch devices just with their CSS.

CSS Media Queries Level 4 indeed is going to provide 2 new features: hover and pointer.


Interaction Media Features: Hover

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.

With the words “primary” pointing device, the W3C draft intended the primary input mechanism system (method or gesture or hardware).

As the draft from the W3C is standardizing, the ‘hover’ Interaction Media Features can have 2 different values:

  • if the primary input mechanism system of the device can hover over elements with ease, we use hover
@media (hover: hover) {
/* ... */
}
  • if the primary input mechanism system of the device cannot hover over elements with ease or they can but not easily (for example a long touch is performed to emulate the hover) or there is no primary input mechanism at all, we use none
@media (hover: none) {
/* ... */
}

Interaction Media Features: Pointer

The pointer media feature is used to query the presence and accuracy of a pointing device such as a mouse. If multiple pointing devices are present, the pointer media feature must reflect the characteristics of the “primary” pointing device, as determined by the user agent.

Again the “primary” pointing device is intended as the primary input mechanism.

The draft from the W3C is standardizing that the ‘pointer’ Interaction Media Feature can have 3 different values:

  • if the primary input mechanism of the device includes a pointing device of limited accuracy, we use coarse
@media (pointer: coarse) {
/* ... */
}
  • if the primary input mechanism of the device includes an accurate pointing device, we use fine
@media (pointer: fine) {
/* ... */
}
  • if the primary input mechanism of the device does not include a pointing device, we use none
@media (pointer: none) {
/* ... */
}

Target specific existing device

We can also combine these two features to match specific existing devices:

/* smartphones, touchscreens */
@media (hover: none) and (pointer: coarse) {
/* ... */
}
/* stylus-based screens */
@media (hover: none) and (pointer: fine) {
/* ... */
}
/* Nintendo Wii controller, Microsoft Kinect */
@media (hover: hover) and (pointer: coarse) {
/* ... */
}
/* mouse, touch pad */
@media (hover: hover) and (pointer: fine) {
/* ... */
}

Note: in case of multiple inputs, hover and pointer are targeting the primary input device.


Target all input devices

Use any-hover and any-pointer to query all input devices.

any-pointer is used to query the presence and accuracy of pointing devices. It does not take into account any additional non-pointing device inputs, and can not be used to test for the presence of other input mechanisms, such as d-pads or keyboard-only controls, that don’t move an on-screen pointer. ‘any-pointer: none’ will only evaluate to true if there are no pointing devices at all present.
/* at least one input mechanism of the device includes a pointing device of limited accuracy. */
@media (any-pointer: coarse) {
/* ... */
}
/* at least one input mechanism of the device includes an accurate pointing device. */
@media (any-pointer: fine) {
/* ... */
}
/* the device does not include any pointing device. */
@media (any-pointer: none) {
/* ... */
}
any-hover: none will only evaluate to true if there are no pointing devices, or if all the pointing devices present lack hover capabilities. As such, it should be understood as a query to test if any hover-capable pointing devices are present, rather than whether or not any of the pointing devices is hover-incapable. The latter scenario can currently not be determined using any-hover or any other interaction media feature. Additionally, it does not take into account any non-pointing device inputs, such as d-pads or keyboard-only controls, which by their very nature are also not hover-capable.
/* one or more available input mechanism(s) can hover over elements with ease */
@media (any-hover: hover) {
/* ... */
}
/* one or more available input mechanism(s) can hover, but not with ease (for example simulating the hovering when performing a long touch) */
@media (any-hover: on-demand) {
/* ... */
}
/* one or more available input mechanism(s) cannot hover or there are no pointing input mechanisms */
@media (any-hover: none) {
/* ... */
}

Conclusions

Remember to use these features only if you are sure that your system is used only by certain type of browsers.

Unfortunately this standard is just a draft at the time I am writing. It is early for these features to have their proper praise: as you can see browser support is still very little widespread.

After all, will there be a new official CSS version 4 including these?

To have a cross-browser and cross-device solution at this moment, you should refer to some JavaScript’s solutions like this one.