JavaScript Element gesturestart Event

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Non-standard
Instance event

What You’ll Learn

The gesturestart event fires when a WebKit multi-touch gesture begins. Learn initial scale / rotation, ongesturestart, gesturechange / gestureend, portable alternatives, and five try-it labs.

01

Kind

Instance event

02

Type

GestureEvent

03

When

Multiple fingers contact

04

Handler

ongesturestart

05

Key fields

scale / rotation

06

Status

Non-standard

Introduction

Pinch-to-zoom and two-finger rotate feel natural on phones. WebKit exposed that motion with a small family of events: gesturestart, gesturechange, and gestureend, using the GestureEvent interface.

gesturestart is the “gesture began” signal—ideal for capturing a baseline scale, marking UI as “gesturing,” or calling preventDefault() early. Other browsers never standardized it. Treat it as an optional Safari path—not the only path.

💡
Beginner tip

On Chrome/Firefox desktop, these listeners often never run. Always feature-detect ("ongesturestart" in window or window.GestureEvent) and keep a Touch / Pointer fallback.

Understanding gesturestart

An instance event that answers: “Did multiple fingers just contact the surface to begin a multi-touch gesture?”

  • Non-standard WebKit proprietary event (not in a public spec).
  • Fires when multiple fingers contact the touch surface.
  • GestureEvent — initial scale (~1.0) and rotation (~0.0).
  • Handlerongesturestart or addEventListener("gesturestart", ...).
  • Familygesturestartgesturechange* → gestureend.

📝 Syntax

Use the event name with addEventListener, or set the handler property:

JavaScript
addEventListener("gesturestart", (event) => { });

ongesturestart = (event) => { };

Event type

A GestureEvent (inherits from UIEvent and Event).

Handy properties

PropertyMeaning
scaleFinger-distance multiplier vs gesture start (1.0 initial; <1 pinch; >1 spread)
rotationDegrees rotated since gesture start (positive = clockwise; initial 0.0)

🔁 Event Order

  1. gesturestart — multiple fingers begin a gesture
  2. gesturechange — repeated while digits move
  3. gestureend — gesture finishes

⚖️ WebKit gestures vs portable APIs

ApproachProsCons
gesturestartBuilt-in start signal + initial scale / rotationNon-standard; WebKit-only
Touch EventsWide mobile supportYou compute pinch math yourself
Pointer EventsMouse + touch + pen unifiedMore setup for multi-pointer tracking
wheel (+ modifiers)Useful on some desktop trackpadsNot a full substitute for multi-touch rotate

⚡ Quick Reference

GoalCode / note
Listen (WebKit)el.addEventListener("gesturestart", fn)
Handler propertyel.ongesturestart = fn
Read zoom factorevent.scale
Read twistevent.rotation
Feature-detect"GestureEvent" in window
MDN statusNon-standard

🔍 At a Glance

Four facts to remember about gesturestart.

Event type
GestureEvent

WebKit proprietary

Means
gesture began

Start of multi-touch

Fields
scale · rotation

Pinch & twist

Status
non-standard

Not for sole use

Examples Gallery

Examples follow MDN Element: gesturestart event. Real pinch gestures need a WebKit touch device; labs also show detect / baseline / fallback paths.

📚 Getting Started

Basic listeners and the handler property.

Example 1 — Log Start scale and rotation

Print GestureEvent fields when a WebKit multi-touch gesture begins.

JavaScript
const stage = document.getElementById("stage");
const out = document.getElementById("out");

stage.addEventListener("gesturestart", (event) => {
  out.textContent =
    "start scale=" + event.scale.toFixed(3) +
    " rotation=" + event.rotation.toFixed(1) + "°";
});
Try It Yourself

How It Works

On unsupported browsers nothing appears until you use the detect / fallback labs.

Example 2 — ongesturestart Property

Same idea using the handler property form.

JavaScript
const stage = document.getElementById("stage");
const out = document.getElementById("out");

stage.ongesturestart = (event) => {
  out.textContent = "ongesturestart scale=" + event.scale.toFixed(3);
};
Try It Yourself

How It Works

Prefer addEventListener when you need multiple listeners or easy removal.

📈 Detect, Baseline & Fallback

Feature-detect WebKit support, capture baseline on gesturestart, keep a touch path.

Example 3 — Feature-Detect GestureEvent

Tell learners whether this engine exposes the proprietary API.

JavaScript
const out = document.getElementById("out");
const supported = typeof window.GestureEvent === "function" ||
  "ongesturestart" in window;

out.textContent = supported
  ? "GestureEvent / ongesturestart looks available (likely WebKit)."
  : "No GestureEvent here — use Touch/Pointer fallback.";

if (supported) {
  document.getElementById("stage").addEventListener("gesturestart", (e) => {
    out.textContent = "Started with scale=" + e.scale.toFixed(3);
  });
}
Try It Yourself

How It Works

Detection strings vary by engine. Treat any positive result as “optional enhancement,” not a guarantee of touch hardware.

Example 4 — Capture Baseline on gesturestart

Store the current scale when the gesture begins, then update live during gesturechange.

JavaScript
const stage = document.getElementById("stage");
const card = document.getElementById("card");
const out = document.getElementById("out");
let base = 1;

stage.addEventListener("gesturestart", (event) => {
  event.preventDefault();
  base = Number(card.dataset.scale || 1);
  out.textContent = "Baseline captured: " + base.toFixed(3);
});

stage.addEventListener("gesturechange", (event) => {
  event.preventDefault();
  const next = base * event.scale;
  card.style.transform = "scale(" + next + ")";
  card.dataset.live = String(next);
});

stage.addEventListener("gestureend", () => {
  card.dataset.scale = card.dataset.live || String(base);
});
Try It Yourself

How It Works

gesturestart is where you lock the starting scale. Calling preventDefault() here (and on change) can reduce the browser’s own page zoom.

Example 5 — Portable touchstart Begin Fallback

When GestureEvent is missing, begin a pinch session when a second finger lands.

JavaScript
const stage = document.getElementById("stage");
const out = document.getElementById("out");
let startDist = 0;

function distance(t0, t1) {
  const dx = t0.clientX - t1.clientX;
  const dy = t0.clientY - t1.clientY;
  return Math.hypot(dx, dy);
}

stage.addEventListener("touchstart", (event) => {
  if (event.touches.length === 2) {
    startDist = distance(event.touches[0], event.touches[1]);
    out.textContent = "pinch began (touchstart) dist=" + startDist.toFixed(1);
  }
}, { passive: true });

stage.addEventListener("touchmove", (event) => {
  if (event.touches.length === 2 && startDist > 0) {
    const scale = distance(event.touches[0], event.touches[1]) / startDist;
    out.textContent = "live scale≈" + scale.toFixed(3);
  }
}, { passive: true });

if ("GestureEvent" in window) {
  stage.addEventListener("gesturestart", (event) => {
    out.textContent = "gesturestart scale=" + event.scale.toFixed(3);
  });
}
Try It Yourself

How It Works

Begin on touchstart (when touches.length === 2) mirrors gesturestart. Keep GestureEvent as an optional WebKit shortcut.

🚀 Common Use Cases (WebKit / Learning)

  • Reading Safari / iOS samples that mention GestureEvent.
  • Optional Safari enhancement on top of a Touch Events core path.
  • Photo / map demos that capture baseline zoom when a pinch begins.
  • Interview questions comparing proprietary vs standard input APIs.
  • Understanding why cross-browser libraries roll their own pinch math.

🔧 How It Works (When Supported)

1

Two+ fingers contact

gesturestart fires; capture baseline (scale ≈ 1.0).

Start
2

Fingers move

gesturechange updates scale / rotation.

Change
3

Preview updates

Apply live CSS transforms during gesturechange.

Preview
4

gestureend closes

Commit final values; the lifecycle that began on gesturestart ends.

📝 Notes

  • MDN: Non-standard — status banner required before What You’ll Learn.
  • Not Deprecated or Experimental on the MDN Element page for this event.
  • WebKit proprietary—not for sole use in cross-browser products.
  • Prefer Touch / Pointer math (or library helpers) as the default path.
  • Related learning: gestureend, gesturechange, gotpointercapture, addEventListener(), JavaScript hub.

Non-standard / WebKit Support

gesturestart is marked Non-standard on MDN. Logos use the shared browser-image-sprite.png sprite from this project. Expect WebKit/Safari paths only—always ship a Touch or Pointer fallback.

Non-standard

Element gesturestart

Proprietary WebKit multi-touch gesture begin signal; not a portable primary API.

WebKit Not standardized
Google Chrome No GestureEvent; use Touch/Pointer
No
Mozilla Firefox No GestureEvent; use Touch/Pointer
No
Apple Safari WebKit GestureEvent (esp. iOS)
WebKit
Microsoft Edge No GestureEvent; use Touch/Pointer
No
Opera No GestureEvent; use Touch/Pointer
No
Internet Explorer No
No
gesturestart Non-standard

Bottom line: Use GestureEvent only as an optional Safari enhancement; compute pinch with Touch/Pointer Events for everyone else.

Conclusion

gesturestart is a Non-standard WebKit signal that a multi-touch gesture began. Use it to capture baseline state, feature-detect carefully, and keep Touch / Pointer Events as your portable foundation.

Continue with gotpointercapture, addEventListener(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect before attaching GestureEvent listeners
  • Keep a Touch / Pointer pinch implementation as the default
  • Document that the API is WebKit-only / Non-standard
  • Test on real iOS Safari hardware when you enhance with it
  • Pair with gesturechange / gestureend for full lifecycle

❌ Don’t

  • Ship pinch/zoom that only listens for gesturestart
  • Assume Chrome or Firefox will fire these events
  • Ignore browser page-zoom side effects (consider preventDefault)
  • Treat Non-standard as “fine for all production users”
  • Overwrite ongesturestart if you need multiple listeners

Key Takeaways

Knowledge Unlocked

Five things to remember about gesturestart

WebKit gesture began—Non-standard; prefer portable begin on touchstart.

5
Core concepts
📄 02

GestureEvent

scale · rotation

API
🚫 03

Non-standard

WebKit only

Status
🔄 04

Touch fallback

portable pinch

Replace
🎯 05

Feature-detect

optional enhance

Pattern

❓ Frequently Asked Questions

It is a proprietary WebKit event fired when multiple fingers contact the touch surface, starting a new gesture. After that, gesturechange may fire while fingers move, and gestureend fires when the gesture finishes. MDN marks it Non-standard.
MDN marks it Non-standard only on the Element gesturestart page — not Deprecated and not Experimental. Still avoid it as the primary API in cross-browser apps.
gesturestart begins the gesture, gesturechange fires while fingers move, and gestureend fires when the multi-touch gesture finishes.
It is WebKit-specific. Expect Safari on iOS (and related WebKit contexts). Chrome, Firefox, and Edge generally do not implement this event.
At the start of a gesture, scale is typically 1.0 and rotation is typically 0.0. Use gesturestart to capture baseline state before later updates.
For portable pinch/zoom, prefer Touch Events or Pointer Events and begin tracking when a second finger lands (for example touchstart with touches.length === 2). Feature-detect GestureEvent only as an optional Safari enhancement.
Did you know?

MDN lists gesturestart under “Not part of any specification.” That is why libraries rarely depend on it alone—standards favor Touch Events and Pointer Events for multi-touch.

Next: gotpointercapture

Learn when setPointerCapture() succeeds and drag capture begins.

gotpointercapture →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful