Back to the Blog
Essay

Hover on Mobile: Why It Breaks and What to Use Instead

Hover effects do not work on touch devices, and tapping them leaves buttons stuck mid-glow. Here is the one media query that fixes it, plus real tap states.

By Social Catnip
Jun 18, 20268 min read

Short answer: hover effects don't really work on mobile, because phones and tablets have no cursor to hover with. A touch device has nothing hovering over the screen until a finger lands on it — and the moment it lands, that's a tap, not a hover. So the safe move is to stop relying on :hover for anything important on touch, scope your hover styles to real cursors with @media (hover: hover) and (pointer: fine), and design proper tap and :active states for everything else. Do that and your buttons stop getting stuck mid-glow on a thumb. That's the whole post in one paragraph, but the gotchas are worth your next five minutes.

I've spent seven years building on Webflow, and "the hover thing is broken on my phone" is one of those bug reports that lands in my inbox roughly forever. It's almost never a real bug. It's a designer leaning on :hover to reveal something — a caption, a menu, a CTA — and then being surprised that the device with no mouse can't do the one thing that needs a mouse. The fix is mostly a mindset change, plus one media query you'll use for the rest of your career.

Why :hover is broken on touch devices

A mouse pointer can sit over an element without clicking it. That hovering, in-between state is the entire premise of :hover. Your finger doesn't have an in-between state — it's either off the glass or it's tapping. There's no "hovering my thumb near the button" signal for the browser to read.

So when a touch user taps a :hover element, the browser does its best to be helpful: it fires the hover styles and the tap at basically the same instant. On a fast interaction that's invisible. The problem is everything you built that assumed hover is a separate, dwell-able state — a dropdown that only opens on hover, a card overlay that only appears on hover, a tooltip that needs the cursor to linger. On a phone, those range from awkward to completely unreachable.

The honest rule: on touch, hover is a bonus, never a requirement. If a feature is only reachable by hovering, a third of your visitors can't reach it. Build the touch path first, then sprinkle hover on top for the people holding a mouse.

The "sticky hover" gotcha nobody warns you about

Here's the one that generates the actual bug reports. On many mobile browsers, when you tap a :hover element, the hover style sticks. The button stays lit, the card stays flipped, the color stays inverted — until you tap somewhere else on the page to clear it. It looks exactly like a stuck, half-broken UI, because it kind of is.

It happens because the browser applies :hover on tap and then has no "mouse left the element" event to remove it — your finger already lifted off. So the style just hangs around like a guest who didn't read the room.

You'll see it most on:

  • Buttons that change background color on hover
  • Cards with a hover overlay or zoom
  • Nav items that underline or shift on hover

The clean fix isn't a JavaScript patch or a touchend listener. It's to stop sending hover styles to touch devices in the first place — which is exactly what the next section does.

The one media query that fixes it: @media (hover: hover)

CSS media features let you ask the browser what kind of input the device actually has. Two of them matter here:

  • hover: hover — the device can hover (it has a mouse or trackpad).
  • pointer: fine — the device has a precise pointer (again, a real cursor, not a fat fingertip).

Combine them and you've drawn a line between "real cursor" and "touchscreen." Wrap your hover styles in it:

.button {
  background: #1e40af;
  transition: background 0.2s ease;
}

/* Only devices with a true hovering cursor get this */
@media (hover: hover) and (pointer: fine) {
  .button:hover {
    background: #1d4ed8;
  }
}

Now a desktop user with a mouse gets the hover glow, and a phone user gets nothing extra on tap — no sticky state, no half-lit button, no bug report. The hover style is simply invisible to devices that can't honor it.

Why both conditions? Some hybrid devices (a Surface, a laptop with a touchscreen) report hover: hover but switch pointer types depending on whether you're using the mouse or the screen. Pairing pointer: fine keeps the styles aimed at genuine cursor use and out of the way of touch. It's a belt-and-suspenders thing, and the suspenders are free.

Design real tap and :active states instead

Killing the sticky hover is half the job. The other half is giving touch users feedback when they do tap — because a button that does nothing visible when pressed feels broken even when it works.

That's what :active is for. It fires while the element is being pressed, on both mouse and touch, and it clears itself the moment you let go. No stickiness, by design.

.button:active {
  transform: scale(0.97);
  background: #1e3a8a;
}

So the full pattern is: a neutral base state everyone sees, a hover state scoped to real cursors, and an :active state for the press itself.

.button { background: #1e40af; }

@media (hover: hover) and (pointer: fine) {
  .button:hover { background: #1d4ed8; }
}

.button:active { background: #1e3a8a; }

One more freebie while you're in there: kill the gray flash some mobile browsers paint on tap with -webkit-tap-highlight-color: transparent;, and make sure your tap targets are at least 48×48 px. A hover effect nobody can comfortably hit is still a miss, mouse or no mouse.

Doing this in Webflow without touching code

Webflow gives you hover states in the Style panel, and it'll happily let you build a whole interaction that only works with a mouse — it won't stop you, the same way a hardware store will sell you a ladder without asking your plans. Two things keep you out of trouble.

First, treat any hover interaction in Webflow as decoration, not navigation. If a menu, a CTA, or a piece of content can only be reached by hovering, rebuild it so a tap reaches it too — a click-to-open dropdown, a CTA that's just visible, a card that doesn't hide its contents.

Second, for the sticky-hover styling itself, drop the @media (hover: hover) and (pointer: fine) block into an Embed element or your site's custom code and target your class there. It's a couple of lines, it ports straight over from a hand-coded site, and it does the exact same job inside Webflow that it does anywhere else. The platform changes; the media query doesn't.

If your hover effects are also making the page feel heavy or janky on a phone, that's usually a performance problem wearing a hover costume — worth a read of our notes on diagnosing and resolving Webflow performance issues. And if you'd rather hand the whole thing to someone who's wired this on a hundred-plus sites, that's what our Webflow development agency does for a living.

Frequently asked questions

Do hover effects work on mobile?

Not reliably. Phones and tablets have no cursor, so there's no true hover state — a tap fires hover and the click at the same time, and the hover style often sticks until you tap elsewhere. Treat hover as a desktop-only bonus and build a tap path for anything that matters.

How do I disable hover on touch devices?

Wrap your hover styles in @media (hover: hover) and (pointer: fine) { ... }. Devices without a real cursor simply never receive those styles, which kills the sticky-hover problem at the source. No JavaScript required.

What is sticky hover and how do I fix it?

Sticky hover is when a tapped element keeps its hover style until you tap somewhere else, because touch never fires a "mouse left" event. The fix is to scope hover to real cursors with the (hover: hover) media query so touch devices don't get the hover style at all.

Should I use :active or :hover for mobile feedback?

Use :active. It fires while an element is being pressed on both mouse and touch and clears itself on release, so it never sticks. Pair a cursor-scoped :hover for desktop with an :active state that works everywhere.

Does @media (hover: hover) work in all browsers?

Yes — it's supported across all current major browsers, desktop and mobile. Older devices that don't understand it simply ignore the block, which means they don't get hover styles either. That's a safe failure for touch.


Hover isn't broken so much as misunderstood: it's a desktop affordance we keep asking a touchscreen to perform. Scope it to real cursors, design honest tap states, and the bug reports stop. If your site's hover behavior is doing something genuinely weird on phones and you don't want to chase it yourself, tell us what it's doing and we'll take a look.

Want this for your team?

Send us a brief and we'll come back with a fixed-price plan in 48 hours.