touch-input

Installation
SKILL.md

Designing for the Thumb

Assume the pointer is coarse, imprecise, attached to a hand that covers part of the screen, and incapable of hovering. That single assumption decides most of what follows: hit areas grow past their visuals, hover reveals but never enables, feedback arrives on press rather than on release, and every gesture has to declare which axis it wants before the browser has to guess. Design the touch version as the real one and let the fine-pointer version be the variant — the reverse produces interfaces that are technically usable on a phone and miserable in practice. gestures owns everything that happens once the finger starts moving — velocity, springs, rubber-banding, mid-flight interruption; this skill stops at the moment of contact: size, placement, latency, and which axis wins. Keyboard order, focus and ARIA are a11y; whether the app reads as installed is native-feel.

Work in the project's existing responsive and styling system. If it has a hover: variant strategy, a size-* scale, or a touch-target utility, extend that rather than adding raw media queries beside it. Check whether an interaction library (Vaul, Embla, use-gesture, Radix) already owns touch-action and pointer capture on the component you are touching — two things setting touch-action on the same element is a bug that only reproduces on device. If the project targets desktop only today, add capability queries anyway; they cost nothing and a touchscreen laptop is already in the wild.

Topic Reference
A bug that only reproduces on an iPhone Open references/platform-quirks.md when something works everywhere except iOS Safari — input zoom, video autoplay, viewport height, tap highlight, scroll locking.

Core Principles

  1. The hit area is 44×44; the visual can be anything. Apple's HIG sets 44×44pt as the minimum comfortable target, and a 24px icon button with a 24px hit area is the single most common touch defect. Keep the icon at 24px and expand the target with min-width: 44px; min-height: 44px, or a pseudo-element at inset: -10px. Exception: a target inside a run of inline text cannot be 44px tall without wrecking the line — WCAG 2.2 SC 2.5.8 puts the hard floor at 24×24 CSS px and demands clear spacing whenever you sit under 44.

  2. Adjacent targets need dead space between them. The finger's contact patch is far wider than the single point the browser reports, so two hit areas that touch will fire the wrong one at the edges. Leave at least 8px of untargeted space between independent controls (house default), and check that expanded hit areas do not overlap — a delete whose invisible padding reaches under a confirm is a data-loss bug that no screenshot shows. Exception: segmented controls, paginators and calendar grids, where the options are adjacent by design and none is destructive.

  3. Gate hover on capability, never on width. Touch devices fire :hover on tap and leave the state stuck until the next tap elsewhere. Wrap every hover style in @media (hover: hover) and (pointer: fine) (Emil Kowalski). A viewport-width breakpoint is the wrong test: a touchscreen laptop is wide and coarse, and a phone in a desktop-mode browser is neither. Exception: a purely decorative cursor-follow effect may gate on (pointer: fine) alone, since it has no state to get stuck in.

Installs
4
Repository
agentsorg/benji
GitHub Stars
1
First Seen
Aug 2, 2026
touch-input — agentsorg/benji