Hover Effects That Work Everywhere: Designing Card Interactions in React
Hover is a hint, not a feature
A good hover effect feels like the interface noticed you. A card leans toward the pointer, an image eases forward, a short line of detail slides into view. It is one of the cheapest ways to make a page feel alive, which is exactly why it gets overused.
The trouble is that hover only exists for one kind of input. A mouse can rest over something without pressing it. A finger cannot. A keyboard user never hovers at all. So every hover effect you design is really a question: what happens for everyone who cannot hover? This guide works through that question for the most common card interactions, using several of today's additions to the Uncode catalog as examples.
Sort your effects into decoration and content
Before writing any code, split hover effects into two groups. Decoration is anything that makes the card feel responsive without changing what it says: a tilt, a glow, a scale, a spotlight under the cursor. Content is anything that only becomes visible on hover: a description, a price, a set of tags, a button.
Decoration can be lost on touch and nobody is worse off. The Tilt Card is a good example. On a laptop it rotates away from the pointer and drags a soft light across its surface. On a phone it simply sits there as a well designed card, and that is fine, because the tilt never carried any information.
Content is different. If a card hides its description until hover, a phone user may never see it, and a keyboard user certainly will not unless you do extra work. The Card Hover Reveal slides a frosted panel up over the image with services, stack and a short profile. That is a lovely moment with a mouse, but the panel holds real information. Treat it as content and plan for the other inputs from the start.
Give touch screens their own answer
Touch browsers try to be helpful by firing a fake hover on the first tap. Sometimes that reveals your hidden panel, sometimes it also follows the link, and sometimes it leaves the card stuck in its hover state until the person taps somewhere else. None of those are designs, they are accidents.
The cleanest fix is to only apply hover styles where hover actually exists. Tailwind can do this with a custom variant built on the (hover: hover) media query, and in plain CSS you can wrap hover rules in @media (hover: hover) and (pointer: fine). In JavaScript, window.matchMedia("(hover: hover)") tells you whether to attach pointer move listeners at all, which also saves work on phones.
Then decide what touch users get instead. For a reveal card, the simplest answer is often to show the detail panel by default on small screens, perhaps in a more compact form. For an avatar that expands into a profile card, like the Avatar Hover Card, a tap that toggles the card open and a second tap or an outside tap to close it is more honest than relying on the browser's fake hover.
Uncode UI
Build with AI, not against it.
Over 1,400 React and Tailwind components that run live in the browser, with a prompt ready to paste into Claude, Cursor or v0. Plus a community of people building real sites with AI.
Make focus do what hover does
Keyboard users move through a page with Tab. If your card is a link or contains a button, it will receive focus, and that focus should trigger the same reveal as hover. In Tailwind this is mostly a matter of pairing variants: wherever you write group-hover:, also write group-focus-within:. The focus-within version is important because focus usually lands on a link or button inside the card, not on the card itself.
In React components that track hover in state, the same idea applies. If you have onMouseEnter and onMouseLeave, add onFocus and onBlur on the wrapper, or better, switch to pointer and focus events together. Then check that the revealed content is not just visible but reachable: if the panel contains a button, Tab should land on it after the panel opens, and Escape should close anything that floats over other content.
Also make the focus ring obvious. Heavy hover styling can make people forget the default outline, and a tilted card with no visible focus state is a dead end for anyone navigating by keyboard.
Keep tilt and parallax gentle
3D tilt is the effect most likely to go from charming to tiring. A few habits keep it on the right side.
Limit the angle. Somewhere around ten to fifteen degrees reads as depth; much more and the card starts to feel like it is being thrown around. The Standard Card uses a spring on the rotation, so the card eases toward the pointer instead of snapping, which matters more than the exact angle.
Reset on leave. A card that stays tilted after the pointer has gone looks broken. Every tilt component should animate back to flat when the pointer leaves or the window loses focus.
Avoid tilting text heavy cards. Rotation makes small text harder to read, and some people find perspective motion uncomfortable. Use tilt on cards with a short title and a visual, not on cards someone is meant to read carefully.
Respect prefers-reduced-motion. When it is set, drop the tilt and parallax entirely and keep a simple color or shadow change instead. Framer Motion's useReducedMotion hook makes this a one line check in React.
Let ambient motion run quietly
Some cards move even when nobody touches them. The Glowing Stars Card lights a few random dots every few seconds and floods the whole grid with light on hover. Ambient effects like this work best when they are slow, small and limited to one card in view. A grid of twelve cards all twinkling at once turns into noise and pulls attention away from the content.
Two practical rules help. Pause ambient loops when the card is off screen, using an IntersectionObserver, so a long page is not running timers it cannot show. And keep the hover version of the effect as a stronger form of the idle one, not something unrelated, so the interaction feels like a natural response rather than a second animation stacked on top.
Tie the effect to what the card does
The best hover effects explain the card. A card that opens a gallery can scale its image forward, as if inviting a closer look. A card that leads to a profile can expand into that profile. The Icon 3D Hover turns its sliced cube icon and fills the title with a solid band on hover, which works as a clear "this is clickable" signal for a navigation tile.
When the effect has no relationship to the destination, it becomes decoration for its own sake. A Flip Hover card that spins once is great for a playful portfolio grid, but on a pricing page it would only distract. Pick one effect per card type and use it consistently across the page, so people learn what hover means on your site.
Watch performance on large grids
Hover effects run on every pointer move, so small costs multiply quickly. Animate transform and opacity wherever you can, since they can usually be handled without recalculating layout. Avoid animating width, height, top or box-shadow on dozens of cards at once.
For pointer tracking, store the position in a ref or a motion value instead of React state when possible. Updating state on every move re-renders the component each time, while motion values from Framer Motion update the style directly. If you do use state, as several simple tilt components do, keep the component small so the re-render stays cheap. And remove global listeners when the card unmounts; a forgotten mousemove handler on window is one of the most common leaks in hover components.
A short checklist before you ship
Run through these with any card interaction:
- Is every piece of information visible without hover, or reachable by tap and by keyboard?
- Does focus trigger the same reveal as hover, with a visible focus ring?
- Are hover styles limited to devices that can actually hover?
- Does the card return to rest when the pointer leaves?
- Is motion reduced or removed when the user asks for it?
- Do ambient loops pause off screen, and are listeners cleaned up on unmount?
If the answer to all of them is yes, the hover effect is doing its proper job: adding a moment of delight for people with a mouse while everyone else still gets a complete, usable card. All the cards mentioned here are in the catalog, and you can pull any of them straight into your editor through the Uncode MCP connection to try these ideas on your own components.
Uncode UI
Build with AI, not against it.
Over 1,400 React and Tailwind components that run live in the browser, with a prompt ready to paste into Claude, Cursor or v0. Plus a community of people building real sites with AI.