Touch Support
title: "Touch Support — Accessible Drag and Drop on Mobile" description: "Learn how to make drag-and-drop accessible on touch devices with proper touch handling, large targets, and ARIA support for mobile screen readers." weight: 10 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, drag-drop]
Touch-based drag and drop needs larger targets, touch-action CSS, and proper ARIA for mobile screen reader users on iOS and Android.
## What You'll Learn
How to implement accessible drag-and-drop for touch devices with proper touch handling and screen reader support.
## Why It Matters
Mobile users rely on touch. Drag on mobile needs to handle touch events, prevent scrolling conflicts, and work with VoiceOver and TalkBack.
## Real-World Use
A user on an iPhone opens a todo list. They long-press a task to enter reorder mode, then drag it to a new position using large touch targets. VoiceOver announces each position change.
## Touch Drag Handle
```html
<li role="listitem" aria-label="Task 3: Pay bills">
<button aria-label="Reorder: Pay bills"
class="drag-handle touch-handle"
touch-action="none">
<svg aria-hidden="true" width="28" height="28">...</svg>
</button>
<span>Pay bills</span>
</li>
Touch JavaScript
let touchStartY = 0;
let currentItem = null;
document.addEventListener('touchstart', function(e) {
const handle = e.target.closest('.touch-handle');
if (!handle) return;
currentItem = handle.closest('[role="listitem"]');
touchStartY = e.touches[0].clientY;
currentItem.style.opacity = '0.7';
}, { passive: true });
document.addEventListener('touchmove', function(e) {
if (!currentItem) return;
e.preventDefault();
const touchY = e.touches[0].clientY;
const delta = touchY - touchStartY;
currentItem.style.transform = `translateY(${delta}px)`;
}, { passive: false });
document.addEventListener('touchend', function(e) {
if (!currentItem) return;
// Determine new position based on touch end position
const items = Array.from(currentItem.parentElement.children);
const currentIndex = items.indexOf(currentItem);
const moved = Math.round(
(parseInt(currentItem.style.transform.replace('translateY(', '')) || 0) / currentItem.offsetHeight
);
if (moved !== 0) {
const newIndex = Math.max(0, Math.min(items.length - 1, currentIndex + moved));
// Move item
}
currentItem.style.opacity = '1';
currentItem.style.transform = '';
currentItem = null;
});
Common Mistakes
1. Small touch targets
Touch drag handles must be at least 44x44px. 48x48px is better.
2. No touch-action CSS
Set touch-action: none on drag handles to prevent page scrolling during drag.
3. Passive touch listeners wrong
Use { passive: false } on touchmove to prevent default scrolling.
4. No VoiceOver/TalkBack support
ARIA attributes and live regions work with mobile screen readers too.
5. Visual feedback missing
Provide visual feedback (opacity, transform) during touch drag.
Practice Questions
1. What is the minimum touch target size for drag handles? 44x44 pixels minimum, 48x48px recommended for mobile.
2. What CSS property prevents page scrolling during touch drag? touch-action: none on the drag handle element.
3. Why should touchmove use { passive: false }? To allow e.preventDefault() to prevent scrolling while dragging.
Challenge: Create a touch-enabled reorderable list that works on iOS and Android with VoiceOver and TalkBack.
FAQ
Mini Project
Build a touch-enabled reorderable list with 44x44px drag handles, touch-action CSS, visual feedback, and screen reader announcements.
What's Next
Learn how to perform Drag and Drop Testing to verify accessibility.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro