Use Pointer Events

The web has three input event families - mouse, touch and pointer - and Pointer Events unify all of them. One set of handlers covers a mouse, a finger, a stylus and a trackpad, which removes an entire category of duplicate-handler bugs.

Our input layer uses Pointer Events where available and falls back to touch and mouse handlers otherwise. The fallback path is short, because the rest of the game sees the same named actions either way.

The one event people forget is pointercancel, which fires when the system interrupts a gesture - a notification, a system gesture, a call. Without handling it, a control can be left stuck down.

Seven browser behaviours to disable

Each of these is a browser default that makes sense for documents and breaks games. All seven are two or three lines.

BehaviourFixSymptom if missed
Page scrolling on dragtouch-action: none on the stageThe page scrolls while you steer
Default gesture handlingpreventDefault on pointer events in the stageSame, plus pinch-zoom
Tap highlight flash-webkit-tap-highlight-color: transparentA grey box flashes over every tap on iOS
Text selectionuser-select: none on the stageLong press starts selecting the page
Context menupreventDefault on contextmenuLong press opens a menu mid-game
Double-tap zoomA viewport meta tag and touch-actionThe game zooms when you tap quickly twice
Interrupted gesturesHandle pointercancelA control stays stuck down after an interruption

Advertising keeps Candy Arcade free. Ads never cover gameplay or controls.

Choose a layout per game

There is no universal touch layout, and using one everywhere produces a game that is awkward in most contexts. Our input layer implements twelve schemes and each game declares which it needs.

  • Finger-follow: the character eases toward your finger's position. Best for single-axis movement, because it is precise and needs no buttons.
  • Tap-anywhere: the whole screen is the button. The best possible layout for a single-action game and the most accessible design available.
  • Touch-and-hold: hold duration is the input. Used for thrust, where position is irrelevant.
  • Directional pads plus an action button: necessary when two independent inputs are needed, as in the platformers.
  • Swipes: suit discrete inputs. Reliable for lane changes and grid direction, unreliable for continuous movement.
  • Drag-to-steer: direct following for free 2D movement, which beats a virtual stick in our testing.

The general preference is to make the target as large as possible. Where a game can use the whole screen, it should.

Keep controls out of the way

The defining difference between touch and mouse is that your hand is on the screen. A thumb occupies a couple of square centimetres, and whatever is underneath it is invisible while you play.

Our rule: controls sit in the lower corners, and nothing gameplay-critical is drawn in the lower third on phones. Where a game needs full-width movement along the bottom - the cart in Candy Rush, the basket in Candy Catcher - the character follows your finger anywhere on the lower half instead of using buttons, so the hand stays below the action.

Controls are also semi-transparent, around twenty percent opacity rising on press. They stay clearly visible while obscuring as little as possible, which matters because on a phone every pixel of play area is contested.

Size and spacing

Fingers are imprecise, the contact area is larger than the visual point of contact, and there is no hover state to confirm what you are about to press.

Our on-screen controls are 64 pixels across, and every interactive element on the site is at least 44 pixels on a coarse pointer, applied through a pointer: coarse media query so desktop layouts stay compact.

Spacing matters as much as size. Two adjacent 64-pixel buttons with no gap still produce mispresses at the boundary, so ours are separated.

Show them only where they belong

On-screen controls on a desktop are clutter, and they suggest the keyboard does not work. Ours are hidden entirely on devices with a fine pointer, using both a CSS media query and a runtime touch check.

The belt-and-braces approach matters because neither test alone is reliable: some laptops report touch support without being used that way, and some tablets with keyboards report both. Using both a hover-capable media query and a touch-points check gets it right in the common cases.

Test with a thumb

The single highest-value mobile test available, and it takes thirty seconds: play the game on a real device, held the way you would actually hold it, with the hand you would actually use.

A desktop device emulator cannot reveal occlusion, because it has no thumb. A control that works perfectly in emulation can be unusable in practice because the hand operating it covers the thing you need to see.

Test with a case on, too. It changes where your thumb naturally rests more than you would expect.

Common mistakes

  • Not setting touch-action: noneThe page scrolls while the player is trying to steer, which makes the game feel broken.
  • Ignoring pointercancelAn interrupted gesture leaves a control stuck down, so the character keeps moving.
  • One control layout for every gameA virtual stick on a one-button game is worse than tap-anywhere in every respect.
  • Controls over the play areaA thumb hides a couple of square centimetres. Keep gameplay out of the lower third.
  • Showing touch controls on desktopThey are clutter and they imply the keyboard does not work.
  • Testing touch with a mouseAn emulator has no thumb, so it cannot reveal the most important difference.

Practical tips

  • Where a game says tap anywhere, the whole screen really is the button.
  • Finger-follow games are more precise than they look; move your finger rather than tapping.
  • Swipes are reliable for lane changes and grid direction, less so for continuous movement.
  • Controls are translucent so you can see through them; they brighten on press.
  • On desktop, the keyboard is the intended input and touch controls are hidden.

Key takeaways

  • Pointer Events unify mouse, touch and pen behind one code path - including pointercancel.
  • Seven browser defaults need disabling, each in two or three lines.
  • Pick a control scheme per game; prefer the largest possible target.
  • Keep gameplay out of the lower third, where a hand will be.
  • 44 pixels minimum, 64 preferred, with gaps between controls.
  • Test with a real thumb on a real device - an emulator cannot show occlusion.

Frequently Asked Questions

Why do browser games sometimes scroll the page while you play?

Because touch-action has not been set to none on the game area, so the browser treats the drag as a scroll gesture.

What is pointercancel and why does it matter?

It fires when the system interrupts a gesture - a notification or a system gesture. Without handling it, an on-screen control can be left stuck down.

Are virtual joysticks a good idea?

Rarely. Direct finger-following is more precise for free movement, and tap-anywhere is better for single-action games.

Why are the on-screen controls see-through?

So they obscure as little of the play area as possible. They brighten when pressed so the feedback is still clear.

Why do I not see touch controls on my laptop?

They are hidden on devices with a fine pointer, because the keyboard is the intended input there and on-screen buttons would be clutter.

References

  1. Pointer events - MDN Web Docs — The unified input model, including pointercancel.
  2. touch-action - MDN Web Docs — How to prevent browser gesture handling on a game area.

Every external source listed here has been read. We do not cite sources we have not checked, and we do not invent references. See our fact-checking policy.