touchAction

touchAction

Control browser touch gesture handling

The touchAction plugin controls browser touch gesture handling on draggable elements. Sets the CSS touch-action property to prevent conflicts between dragging and browser behaviors like scrolling, zooming, or context menus.

touchAction('manipulation'); // Default - allow basic gestures, disable others
touchAction('none'); // Disable all browser touch behaviors
touchAction('pan-y'); // Allow vertical scrolling only
touchAction(false); // Don't set touch-action (browser default)

Note: TouchAction is included by default with 'manipulation' mode for optimal touch device compatibility.

Basic Usage

import { Draggable, touchAction } from '@neodrag/vanilla';

const manipulation = document.getElementById('manipulation');
const none = document.getElementById('none');
const panY = document.getElementById('pan-y');
const defaultElement = document.getElementById('default');

new Draggable(manipulation, [touchAction('manipulation')]);
new Draggable(none, [touchAction('none')]);
new Draggable(panY, [touchAction('pan-y')]);
new Draggable(defaultElement, [touchAction(false)]);

Touch Action Values

touchAction('manipulation'); // Best for most draggable elements
touchAction('none'); // Complete touch gesture control
touchAction('pan-y'); // Vertical scrolling allowed
touchAction('pan-x'); // Horizontal scrolling allowed

All Available Values

// Basic gestures
touchAction('auto'); // Browser default behavior
touchAction('none'); // Disable all touch behaviors
touchAction('manipulation'); // Allow pan and zoom, disable others

// Directional panning
touchAction('pan-x'); // Horizontal panning only
touchAction('pan-y'); // Vertical panning only
touchAction('pan-left'); // Left panning only
touchAction('pan-right'); // Right panning only
touchAction('pan-up'); // Up panning only
touchAction('pan-down'); // Down panning only

// Zoom control
touchAction('pinch-zoom'); // Pinch-to-zoom only

// CSS globals
touchAction('inherit'); // Inherit from parent
touchAction('initial'); // CSS initial value
touchAction('unset'); // CSS unset value

// Disable plugin
touchAction(false); // Don't set touch-action property
touchAction(null); // Same as false

Dynamic Configuration

import {
  Draggable,
  touchAction,
  Compartment,
} from '@neodrag/vanilla';

const element = document.getElementById('draggable');
const modeSelect = document.getElementById('mode-select');
const scrollToggle = document.getElementById('scroll-toggle');
const valueDisplay = document.getElementById('value-display');

let mode = 'manipulation';
let allowScroll = false;

const touchActionComp = new Compartment(() => {
  if (mode === 'disabled') return touchAction(false);
  if (allowScroll) return touchAction('pan-y');
  return touchAction(mode);
});

function updateDisplay() {
  let value;
  if (mode === 'disabled') value = 'not set';
  else if (allowScroll) value = 'pan-y';
  else value = mode;

  valueDisplay.textContent = `CSS: touch-action: ${value}`;
}

new Draggable(element, () => [touchActionComp]);

modeSelect.addEventListener('change', (e) => {
  mode = e.target.value;
  touchActionComp.current = touchAction(
    mode === 'disabled' ? false : allowScroll ? 'pan-y' : mode,
  );
  updateDisplay();
});

scrollToggle.addEventListener('change', (e) => {
  allowScroll = e.target.checked;
  touchActionComp.current = touchAction(
    mode === 'disabled' ? false : allowScroll ? 'pan-y' : mode,
  );
  updateDisplay();
});

updateDisplay();

Device-Specific Usage

Mobile Phones

// Recommended for mobile drag interfaces
touchAction('manipulation'); // Allows pinch-zoom, prevents conflicts

// For full-screen drag experiences
touchAction('none'); // Complete gesture control

Tablets

// Allow some scrolling while dragging
touchAction('pan-y'); // Vertical scrolling + drag

// General purpose
touchAction('manipulation'); // Good default

Desktop with Touch

// Usually less restrictive
touchAction('auto'); // Browser default often works

// For precision drag tools
touchAction('none'); // Disable browser interference

Common Use Cases

Modal/Dialog Dragging

// Allow page interaction while dragging modal
touchAction('manipulation'); // Keep pinch-zoom, disable pan

Slider/Range Controls

// Horizontal slider that allows vertical scrolling
touchAction('pan-y'); // Only vertical page scrolling

Game/Interactive Elements

// Complete gesture control for games
touchAction('none'); // Disable all browser behaviors

Canvas/Drawing Applications

// High precision drawing
touchAction('none'); // Disable all browser gestures

Combining with Other Plugins

Mobile-Optimized Setup

const plugins = [
  touchAction('none'), // Disable browser gestures
  threshold({ distance: 8, delay: 50 }), // Prevent accidental drags
  scrollLock({ lockAxis: 'both' }), // Prevent page scrolling
];

Context-Aware Setup

const isMobile = /Mobi|Android/i.test(navigator.userAgent);
const isFullScreen = document.fullscreenElement !== null;

const plugins = [
  touchAction(isFullScreen ? 'none' : 'manipulation'),
  isMobile
    ? threshold({ distance: 10, delay: 100 })
    : threshold({ distance: 3, delay: 0 }),
];

Canvas/Drawing Setup

const plugins = [
  touchAction('none'), // Disable all browser gestures
  threshold({ distance: 1 }), // Very sensitive
  scrollLock({ lockAxis: 'both' }), // Lock scrolling completely
];

Browser Support

Modern Browsers

All modern browsers support touch-action:

  • iOS Safari 9.1+
  • Chrome 36+
  • Firefox 52+
  • Edge 12+

Legacy Fallbacks

For older browsers, touch-action is ignored gracefully:

// Graceful degradation
touchAction('manipulation'); // Newer browsers get optimization
// Older browsers fall back to default behavior

iOS Considerations

iOS Safari has specific behaviors:

// iOS often requires 'manipulation' for best results
touchAction('manipulation'); // Works well on iOS

// 'none' can be aggressive on iOS
touchAction('none'); // Use carefully on iOS

How It Works

The touchAction plugin sets the CSS touch-action property:

  1. Setup phase: Sets element.style.touchAction = value
  2. Browser behavior: Browser respects the property for touch gesture handling
  3. Live updates: Can change touch-action during drag if needed

CSS Applied:

/* Example results */
.draggable {
  touch-action: manipulation;
}
.no-gestures {
  touch-action: none;
}
.vertical-scroll {
  touch-action: pan-y;
}

What touch-action controls:

  • Pan gestures (scrolling)
  • Pinch-to-zoom
  • Double-tap to zoom
  • Context menus (long press)
  • Text selection
  • Browser navigation gestures

API Reference

function touchAction(mode?: TouchActionMode | false | null): Plugin;

Parameters:

  • mode - The touch-action CSS value to apply (default: 'manipulation')

TouchActionMode values:

  • 'auto' - Browser default behavior
  • 'none' - Disable all touch behaviors
  • 'manipulation' - Allow pan and zoom, disable others
  • 'pan-x' - Horizontal panning only
  • 'pan-y' - Vertical panning only
  • 'pan-left', 'pan-right', 'pan-up', 'pan-down' - Directional panning
  • 'pinch-zoom' - Pinch-to-zoom only
  • 'inherit', 'initial', 'unset' - CSS global values
  • false or null - Don’t set touch-action (browser default)

Behavior:

  • Non-cancelable - always applies the CSS property
  • Supports live updates during drag
  • Only sets CSS property in setup phase
  • Works on all modern browsers with graceful degradation

Returns: A plugin object for use with draggable.