# Hover States with Media Query

**MUST** · **ID:** `interactions-hover-media-query` · **Category:** interactions
**Source:** [Rauno](https://interfaces.rauno.me/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/interactions-hover-media-query

> MUST: Gate hover styles behind `@media (hover: hover)` so touch devices never get a flash of sticky hover state on press.

Hover states should not be visible on touch press — use @media (hover: hover)

On touch devices, pressing an element briefly triggers its hover state, causing a flash of the hover style. Wrapping hover declarations in @media (hover: hover) ensures they only apply on devices with a true pointer, like a mouse.

## Rule snippet

```tsx
@media (hover: hover) {
  .btn:hover { background: var(--accent); }
}
```

## Bad — do not do this

`interactions-hover-media-query-bad`

```tsx
export function HoverMediaQueryBad() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4 space-y-3">
        <style>{`
          .hover-bad-btn:hover {
            background: var(--primary);
            color: var(--primary-foreground);
          }
        `}</style>
        <button className="hover-bad-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Upload File
        </button>
        <button className="hover-bad-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Share Link
        </button>
        <button className="hover-bad-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Download
        </button>
      </div>
      <p className="text-xs text-error">Hover state flashes on touch tap — confusing on mobile</p>
    </div>
  );
}
```

## Good — do this

`interactions-hover-media-query-good`

```tsx
export function HoverMediaQueryGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4 space-y-3">
        <style>{`
          @media (hover: hover) {
            .hover-good-btn:hover {
              background: var(--primary);
              color: var(--primary-foreground);
            }
          }
        `}</style>
        <button className="hover-good-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Upload File
        </button>
        <button className="hover-good-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Share Link
        </button>
        <button className="hover-good-btn w-full px-4 py-2 border border-border rounded-lg text-sm text-foreground transition-colors">
          Download
        </button>
      </div>
      <p className="text-xs text-success">@media (hover: hover) — hover only for pointer devices</p>
    </div>
  );
}
```

## References

- [interfaces.rauno.me](https://interfaces.rauno.me/)
- [MDN hover media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/hover)
