Interaction Media Features: What They Can and Can’t Tell You
Media Queries Level 4 introduced four interaction media features — pointer, hover, any-pointer, and any-hover — designed to let sites adapt styling and behavior based on a user’s input devices. They’re broadly supported, though browser implementations still have inconsistencies (recent test results highlight several known bugs).
The common pitch is straightforward: make controls bigger for touchscreens, offer CSS dropdown menus only when hover is available. But these features are often misunderstood, and developers frequently use them as a form of “touch detection” — for example, enabling touch event listeners only when a coarse pointer is reported. That approach stems from a basic misconception about what these queries actually describe.
The primary input problem
pointer and hover only expose the characteristics of what the browser considers the primary pointer input. That determination may not match what the user is actually using. Modern devices blur the lines: a phone or tablet with a paired Bluetooth mouse still nominally reports pointer: coarse and hover: none, even if the user is operating a fine, hover-capable mouse. A Surface-style laptop with both a trackpad and touchscreen will typically report pointer: fine / hover: hover for the trackpad — but a user might be interacting via the coarse, non-hover touchscreen.
For layouts that merely enlarge buttons or disable hover effects, this mismatch is tolerable. But when sites use pointer: coarse as a trigger for drastic changes — such as only listening to touch events — the experience can break entirely for users on multi-input devices.
Note also that interaction media features only cover pointer inputs. They don’t detect keyboards or switch controls at all. In theory, a browser could report pointer: none for a keyboard-only user, but no browser lets users specify that. Assume keyboard accessibility is always required.
any-pointer and any-hover: all inputs, not just the primary
any-pointer and any-hover report the combined capabilities of all available pointer inputs. Multiple values can match simultaneously when different devices have different characteristics — a device with both a mouse and a touchscreen will match both any-pointer: fine and any-pointer: coarse.
This allows more robust media queries: instead of “make controls bigger if the primary input is coarse,” you can write “make controls bigger if any input is coarse,” and similarly for hover-based menus.
One quirk: because these features represent the union of all input capabilities, any-hover: none only evaluates true when no pointer input is hover-capable. That makes it redundant — if no input hovers, any-hover: hover will already be false. You can’t use any-hover: none to detect a mix of hover-capable and non-hover-capable inputs. You might infer a touchscreen from any-pointer: coarse, but that’s an assumption; coarse inputs that support some form of hover aren’t unthinkable (stylus-equipped devices like the Samsung Galaxy Note or Surface already detect hover without contact).
Dynamic environments
Per the specification, browsers must re-evaluate media queries when the user environment changes. Attaching or detaching a Bluetooth mouse on a tablet shifts any-pointer and any-hover; removing a Surface’s type cover can change even the primary input, flipping from pointer: fine to pointer: coarse. Sites that react to these features must handle sudden mid-session changes, not just initial page load.
Event-based detection has its own traps
Media queries can’t say which input is in use right now. JavaScript libraries like What Input? track actual input events to fill that gap — but they only know after the user has already interacted, and they’re easily fooled by synthetic events.
Assistive technologies commonly generate fake mouse events when a keyboard user activates a control, because much legacy content only responds to mouse input. Similarly, enabling “Full Keyboard Support” in iOS fires pointer, touch, and fallback mouse events for external keyboard navigation — the same sequence as a touch interaction. In both cases, event-based heuristics misidentify the input type through no fault of their own.
Don’t lock out inputs
The classic “touch detection” pattern — listen only to touch events when pointer: coarse matches — fails on any device with mixed inputs. On a touch device with a paired mouse, it prevents mouse users from doing anything; on a mouse-driven laptop with a touchscreen, touch users are left stranded.
Think “touch and mouse/keyboard,” not “touch or mouse/keyboard.” If you’re only optimizing event listeners for performance, consider checking any-pointer: coarse, but keep mouse and keyboard listeners attached regardless. Better yet, skip the event-type dilemma entirely and use pointer events, which unify all pointer inputs in a single model.
Offer an explicit choice
A practical middle ground: don’t use media queries (or event trackers) to permanently pick a mode. Use them as hints to offer the user a manual switch. Microsoft Office does this, showing a Touch/Mouse toggle on touch devices by default while hiding it on others. A web app can default to the primary input’s characteristics but let users override, and prompt when a new input type first appears.
Query responsibly
Interaction media features are useful, but only if you understand their limits. pointer and hover describe the browser’s pick for primary pointer; any-pointer and any-hover describe the union of all pointer capabilities. Combine them for educated guesses, and don’t assume those guesses are guaranteed correct.
Don’t…
- Assume a single input type. Touch and mouse/keyboard coexist, and the available inputs can change at any moment.
- Trust only
pointerandhover. The browser’s “primary” input may not be the one in use. - Rely on
hoverat all. Users may be on a non-hover input, andany-hovercan’t detect a mixed set. Hover-based interfaces also fail for keyboard users entirely.
Do…
- Design touch-friendly by default. If
any-pointer: coarseis true, add larger targets and spacing — it won’t hurt mouse users. - Give users control. Offer an explicit toggle between touch and mouse modes, defaulting based on available signals.
- Keep keyboard accessibility in mind. It can’t be detected, so guarantee support unconditionally.



