Skip to main content
🎨 CSS as a design system·Module B6 · Lesson 7
TaskStyle .card with default no-hover state, then apply transform on hover ONLY when @media (hover: hover). .card { padding: 20px; background: #f5f5f5; border-radius: 8px; transition: transform 0.15s; }. @media (hover: hover) { .card:hover { transform: translateY(-2px); } }.

@media (hover: hover): only hover on devices that hover

75 XP6 min
Theory

Hover doesn't exist on touch screens

.card:hover { transform: translateY(-2px); }

On a desktop, this works as expected. On a phone, the user TAPS the card. The browser treats that as "hover" momentarily — the card jumps up — then the click fires. Janky.

The fix: only apply hover styles when the device CAN hover:

@media (hover: hover) {
  .card:hover { transform: translateY(-2px); }
}

On touch screens, the hover styles never apply. No jank.

The (pointer: ...) media query

Hand-in-hand:

@media (pointer: fine) { ... }     /* precise input (mouse / trackpad) */
@media (pointer: coarse) { ... }   /* imprecise (finger / large stylus) */
@media (pointer: none) { ... }     /* no pointer (TV remote-style nav) */

Use coarse to bump touch targets up:

button { padding: 8px 16px; }
@media (pointer: coarse) {
  button { padding: 12px 20px; }   /* bigger tap target on touch */
}

WCAG's 44×44 touch-target rule (A5 lesson 8) is most relevant on coarse pointers.

Don't combine all four

(hover: hover) and (pointer: fine) is over-narrowing. Just (hover: hover) covers 95% of "use cases that imply a mouse" without being too restrictive.

prefers-color-scheme + prefers-reduced-motion

The other "prefers-*" media queries (B5 lesson 5 + A5 lesson 6) are the OTHER 80% of remaining media queries. Together with @container, they cover most of what you need.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 15 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.