Skip to content

Card hover-lift causes text to blur then re-sharpen (sub-pixel scale transform) #18364

@konopkja

Description

@konopkja

Description

On hover, cards that use the Card primitive with hoverEffect="lift" briefly render their text blurred, and the font appears to subtly change weight, before snapping sharp again. Most visible on the staking product cards.

Reproduce: Visit https://ethereum.org/staking/pools/ and hover over any staking provider card. Watch the text during the hover transition — it goes soft/blurry and the glyphs look slightly different, then re-sharpen.

Root cause

The lift hover variant in src/components/ui/card.tsx applies a sub-pixel scale transform:

hoverEffect: {
  lift: "hover:shadow-md hover:scale-[1.005]",
}

combined with the base transition-all duration-300.

transform: scale(1.005) promotes the card to its own GPU compositing layer and rasterizes the text into a bitmap, then scales that bitmap. Because 1.005 is a non-integer scale factor, the text is resampled at fractional pixel boundaries — producing fuzzy edges. Transformed/composited layers also drop sub-pixel (LCD) antialiasing in favour of grayscale AA, which is why the font appears to change rather than just blur. When the transition settles, the browser re-rasterizes the layer at the final scale and the text snaps sharp again — hence "blurred, then sharp."

This is a shared primitive, so it affects every hoverEffect="lift" card across the site, not just staking pools.

Suggested fix

Replace the sub-pixel scale with an integer-pixel translate-based lift (no text resampling), keeping the shadow:

- lift: "hover:shadow-md hover:scale-[1.005]",
+ lift: "hover:shadow-md hover:-translate-y-1",

A translate by a whole-pixel value keeps glyphs on the integer pixel grid, avoiding the resampling blur, and gives a more perceptible lift than a 0.5% scale.

Environment

  • Introduced in commit 368e6110b9 ("feat(ui): apply medium text color, add hoverEffect", 2026-05-27)
  • File: src/components/ui/card.tsx

Metadata

Metadata

Assignees

Labels

bug 🐛Something isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions