Gestures
Reference for touch, pointer, and haptic interaction patterns across iOS, macOS, and web. Use these gestures as building blocks for consistent, platform-appropriate behavior.
The gesture taxonomy
Gestures are the primary input for touch and spatial interfaces. Sitka defines gesture semantics that map to native platform APIs while degrading gracefully to the web. Each gesture has clear recognition thresholds, haptic feedback profiles, and platform-specific mapping.
Tap
Brief touch contact, single point. Used for selection, activation, and precise interaction.
Double Tap
Two quick successive taps. Used for zoom, favorite, or alternate action.
Long Press
Press and hold for 500ms+. Triggers context menus, drag initiation, or haptic confirmation.
Swipe
Quick horizontal or vertical flick. Used for navigation, dismissal, or reveal actions.
Pan / Drag
Continuous tracking of finger movement. Used for scrolling, repositioning, and drawing.
Pinch
Two-finger scale gesture. Used for zoom in/out in maps, galleries, document viewers.
Rotate
Two-finger rotation. Used for image rotation, compass, map orientation.
Force Touch / 3D Touch
Pressure-sensitive interaction. Peek (light) and Pop (deep) on iOS; Force Click on macOS.
Gesture reference
Tap
UITapGestureRecognizeriOS
UITapGestureRecognizer| haptic | UIFeedbackStyle.light |
| velocity | N/A |
| threshold | Touch up inside |
macOS
NSClickGestureRecognizer| haptic | NSHapticFeedbackPattern.generic |
| velocity | N/A |
| threshold | Mouse up inside |
Web
| event | click / touchend |
| haptic | Navigator.vibrate(8) for light |
| threshold | Pointer down/up within 8px tolerance |
Usage guidance
- →Use for buttons, links, toggles, and single-selection controls
- →Minimum target size 44×44 pt (iOS HIG)
- →Double-tap rate limit is 0.3s between taps
- →Avoid nesting tappable elements
Quick reference
| Haptic | UIFeedbackStyle.light |
| Velocity | N/A |
| Threshold | Touch up inside |
Related tokens
Double Tap
UITapGestureRecognizer (numberOfTapsRequired = 2)iOS
UITapGestureRecognizer (numberOfTapsRequired = 2)| haptic | UIImpactFeedbackStyle.medium |
| velocity | N/A |
| threshold | Two tap events within 300ms |
macOS
NSClickGestureRecognizer ( numberOfClicksRequired = 2)| haptic | None |
| velocity | N/A |
| threshold | Two click events within 300ms |
Web
| event | Custom via click/touch timing |
| haptic | Navigator.vibrate(15) |
| threshold | Two clicks within 300ms |
Usage guidance
- →Should not conflict with scroll gesture
- →Provide visual feedback on first tap
- →Disable on form controls to prevent accidental double-submit
- →iOS Maps zoom, Photos favorite are canonical examples
Quick reference
| Haptic | UIImpactFeedbackStyle.medium |
| Velocity | N/A |
| Threshold | Two tap events within 300ms |
Related tokens
Long Press
UILongPressGestureRecognizeriOS
UILongPressGestureRecognizer| haptic | UIImpactFeedbackStyle.heavy |
| velocity | N/A |
| threshold | 0.5s minimum press duration |
macOS
NSPressGestureRecognizer| haptic | NSHapticFeedbackPattern.generic |
| velocity | N/A |
| threshold | 0.5s minimum press duration |
Web
| event | touchstart / mousedown + timer |
| haptic | Navigator.vibrate(50) on recognition |
| threshold | 500ms hold, optional movement tolerance 10px |
Usage guidance
- →Provides haptic confirmation on recognition
- →Shows contextual menu or drag handle after recognition
- →Allow 10px movement tolerance to avoid canceling slight shifts
- →Disambiguation: differentiate from force touch on capable devices
Quick reference
| Haptic | UIImpactFeedbackStyle.heavy |
| Velocity | N/A |
| Threshold | 0.5s minimum press duration |
Related tokens
Swipe
UISwipeGestureRecognizeriOS
UISwipeGestureRecognizer| haptic | UISelectionFeedbackGenerator for edge swipe |
| velocity | 800px/s minimum |
| threshold | 30px translation |
macOS
NSPanGestureRecognizer with velocity tracking| haptic | None |
| velocity | Points/s equivalent |
| threshold | Velocity threshold + minimum translation |
Web
| event | pointermove with velocity tracking |
| haptic | None typically |
| threshold | Velocity > 0.5px/ms OR translation > 50px |
Usage guidance
- →Direction matters: left/right for deck navigation, up/down for dismiss
- →iOS swipe-to-delete/archive pattern (~75% screen width swipe)
- →Should feel decisive — rapid acceleration, not dragging
- →Show arrow/chevron hints for discoverability
Quick reference
| Haptic | UISelectionFeedbackGenerator for edge swipe |
| Velocity | 800px/s minimum |
| Threshold | 30px translation |
Related tokens
Pan / Drag
UIPanGestureRecognizeriOS
UIPanGestureRecognizer| haptic | Optional tick feedback on grid alignment |
| velocity | N/A |
| threshold | 3–5px minimum translation before began |
macOS
NSPanGestureRecognizer| haptic | None |
| velocity | N/A |
| threshold | 3–5pt minimum translation |
Web
| event | pointerdown + pointermove |
| haptic | Optional on alignment |
| threshold | 3px before drag begins |
Usage guidance
- →Uses inertia/flick for deceleration ending (native scroll)
- →Should maintain 1:1 touch fidelity (no lag)
- →Boundary bounces and rubber-banding for overscroll
- →Disable text selection during drag on interactive elements
Quick reference
| Haptic | Optional tick feedback on grid alignment |
| Velocity | N/A |
| Threshold | 3–5px minimum translation before began |
Related tokens
Pinch
UIPinchGestureRecognizeriOS
UIPinchGestureRecognizer| haptic | None by default; optional on scale thresholds |
| velocity | N/A |
| threshold | Scale factor 1.0 baseline |
macOS
NSPinchGestureRecognizer| haptic | None |
| velocity | N/A |
| threshold | Scale 1.0 baseline |
Web
| event | gesturestart / gesturechange / gestureend (touch) |
| haptic | None |
| threshold | Track scale relative to initial distance |
Usage guidance
- →Scale factor typically clamped 0.5x–3x
- →Pinch center point tracks focal point for zoom origin
- →Provide double-tap to zoom alternative
- →Sync with semantic zoom levels (e.g., 100%, 150%, 200%)
Quick reference
| Haptic | None by default; optional on scale thresholds |
| Velocity | N/A |
| Threshold | Scale factor 1.0 baseline |
Related tokens
Rotate
UIRotationGestureRecognizeriOS
UIRotationGestureRecognizer| haptic | None |
| velocity | N/A |
| threshold | Rotation in radians from start angle |
macOS
NSRotationGestureRecognizer| haptic | None |
| velocity | N/A |
| threshold | Radians from start |
Web
| event | gesturestart / gesturechange (rotate) |
| haptic | None |
| threshold | Angle delta from initial touch down |
Usage guidance
- →Often combined with pinch for freeform transform tools
- →Provide 0°, 90°, 180°, 270° snap points for precision tools
- →Display rotation value as overlay during gesture
- →Can conflict with pinch — prefer combined gesture recognizer delegate
Quick reference
| Haptic | None |
| Velocity | N/A |
| Threshold | Rotation in radians from start angle |
Related tokens
Force Touch / 3D Touch
UIForceTouchGestureRecognizer / traitCollection.forceTouchCapabilityiOS
UIForceTouchGestureRecognizer / traitCollection.forceTouchCapability| haptic | UIFeedbackStyle.medium (peek), .heavy (pop) |
| velocity | N/A |
| threshold | Peek at 0.5 force, Pop at 1.0+ (device-dependent) |
macOS
NSPressureGestureRecognizer / trackpad force click| haptic | Taptic Engine feedback |
| velocity | N/A |
| threshold | Force > 1.0 (trackpad click depth) |
Web
| event | pointerdown with pressure property (webkit) |
| haptic | None |
| threshold | pressure >= 0.5 (normalized 0–1) |
Usage guidance
- →Peek shows preview; Pop commits action
- →Provide alternative long-press for devices without pressure sensitivity
- →Disable on accessibility zoom areas
- →Deprecated in iOS 13+ in favor of context menus, but still relevant for macOS trackpad
Quick reference
| Haptic | UIFeedbackStyle.medium (peek), .heavy (pop) |
| Velocity | N/A |
| Threshold | Peek at 0.5 force, Pop at 1.0+ (device-dependent) |
Related tokens
Haptic feedback taxonomy
Sitka defines three haptic categories that map to device Taptic Engine capabilities. Use them consistently to create a coherent tactile language.
Impact
Physical-like collisions and taps
lightLight taps, selection changesmediumStandard actions, button pressheavyDestructive actions, confirmations
Notification
Event-driven signals
successTask completed, save confirmedwarningNon-critical issue, attention needederrorFailed action, validation error
Selection
Continuous feedback during manipulation
clickPicker wheel selectionpickItem chosen from list
Implementation
// iOS Swift: UIImpactFeedbackGenerator for tap
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.prepare()
generator.impactOccurred()
// Web: Navigator.vibrate for tactile feedback
element.addEventListener("click", () => {
navigator.vibrate?.(15) // Light tap
})
// React Native: React Native Haptics
import * as Haptics from 'expo-haptics';
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);