CSS Hover Media Queries for Touch vs Mouse
The CSS @media (hover: hover) media query detects
whether the user's primary input mechanism can hover over elements,
allowing developers to create distinct styles for touchscreens versus
mouse-driven devices. By targeting devices that natively support hover
states, this query prevents unwanted "sticky" hover side effects on
touch devices, streamlines user experience across diverse form factors,
and eliminates the need for JavaScript-based device sniffing.
The Problem with Default Hover States
Historically, developers applied CSS :hover states
globally. While this works seamlessly for a mouse or trackpad, touch
devices like smartphones and tablets lack a continuous cursor.
When a user taps an element with a :hover state on a
touchscreen, mobile browsers simulate hover by triggering the hover
styles upon the first tap. This often causes:
- Sticky hover states: Buttons or cards remain visually active or highlighted even after the tap has concluded, persisting until the user taps elsewhere.
- Double-tap navigation delays: On elements with dropdown menus or tooltips triggered by hover, mobile browsers often require a first tap to simulate hover and a second tap to execute the link click.
How
@media (hover: hover) Works
The hover CSS media feature queries the browser to
evaluate the user's primary input device:
@media (hover: hover): Matches devices where the primary input mechanism can conveniently hover over elements. This includes traditional mice, trackpads, and Nintendo Wiimote-style pointers.@media (hover: none): Matches devices where the primary input mechanism cannot hover at all, or where hovering is inconvenient (such as a basic touchscreen or a stylus that requires contact).
Implementation Example
Instead of declaring hover effects globally, wrap interaction states inside the hover query:
/* Base style for all devices */
.button {
background-color: #007bff;
color: #ffffff;
transition: background-color 0.2s ease;
}
/* Hover styles only apply if the primary device supports true hovering */
@media (hover: hover) {
.button:hover {
background-color: #0056b3;
}
}On a desktop with a mouse, the button darkens on hover. On a smartphone, the hover rule is ignored entirely, ensuring the button returns immediately to its default state after being tapped.
Combining with the Pointer Media Feature
For advanced control, the hover query is frequently
paired with the pointer media query to evaluate accuracy
alongside hover capability:
pointer: fine: Accurate pointing devices, such as a mouse or a stylus.pointer: coarse: Inaccurate pointing devices, such as a finger on a screen.
/* Optimized for desktop environments */
@media (hover: hover) and (pointer: fine) {
.tooltip {
display: block;
}
}
/* Optimized for touch environments */
@media (hover: none) and (pointer: coarse) {
.tooltip {
display: none; /* Provide an alternative UI for touch users */
}
}Hybrid and Dual-Input Devices
Devices like touchscreen laptops or tablets with connected trackpads
support both modalities. The standard @media (hover: hover)
query evaluates only the primary input mechanism.
To account for secondary inputs—such as a user navigating a
touchscreen laptop with an external mouse—CSS provides the
any-hover media feature:
@media (any-hover: hover) {
/* Applies if ANY connected input device supports hover */
.card:hover {
transform: translateY(-4px);
}
}Using @media (hover: hover) ensures responsive designs
adapt to how a user physically interacts with a screen, establishing
clean, predictable feedback on mouse-driven interfaces while keeping
touch interactions intuitive and bug-free.