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.