0Pricing
HTML Academy · Lesson

draggable Attribute and dragstart Event

Make elements draggable and respond to dragstart.

draggable Attribute and dragstart Event is a free HTML Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The draggable Attribute

Any element becomes a drag source when you set draggable="true". Links and images are draggable by default; everything else (divs, lis, spans) requires the explicit attribute. draggable="false" opts an element out of native dragging.

<div draggable="true" id="card">Drag me</div>

The dragstart Event

When the user begins a drag, the source element fires dragstart. This is where you initialize the drag: record which item is moving, optionally style it, and write data to the dataTransfer object that the drop target will read.

card.addEventListener("dragstart", (e) => {
  e.dataTransfer.setData("text/plain", card.id);
});

Without dragstart Nothing Happens

If you mark an element draggable but never handle dragstart, the browser still drags a ghost image but no data is set, so most drop targets refuse the drop. Always pair a draggable attribute with a dragstart listener that stores at least an identifier.

Setting effectAllowed

e.dataTransfer.effectAllowed = "move" in dragstart constrains the operation: "copy", "move", "link", "copyMove", "all", or "none". This drives the cursor that the browser shows and the dropEffect the target may set later.

Adding a Visual Cue

Add a CSS class to the source so it appears dimmed while being dragged: card.classList.add("dragging"). Remove the class in the dragend event so the styling clears whether the drop succeeded or was cancelled with Escape.

Custom Drag Image

By default the browser drags a translucent snapshot of the source. Override it with e.dataTransfer.setDragImage(node, offsetX, offsetY) — pass a hidden DOM element or an Image to display a custom preview at the cursor.

const ghost = document.getElementById("drag-preview");
card.addEventListener("dragstart", (e) => {
  e.dataTransfer.setDragImage(ghost, 20, 20);
});

The dragend Event

dragend fires on the source after the drag completes, whether dropped successfully, dropped on an invalid target, or cancelled. Use it for cleanup — removing the dragging class, hiding ghost previews, restoring opacity.

Detecting Cancellation

Inside dragend, check e.dataTransfer.dropEffect. If the value is "none" the drop did not happen (target rejected, user pressed Escape, or dropped outside the page). Otherwise it equals the effect the drop target chose ("move", "copy", "link").

Drag on Touch Devices

Native drag and drop is desktop-first. On touch devices the API barely works without a polyfill or a Pointer Events-based replacement. For mobile-friendly reorder UIs prefer libraries like SortableJS or dnd-kit, which abstract over both event models.

Accessibility Concerns

Native drag and drop is not keyboard-accessible — keyboard-only users cannot reorder items. Always provide an alternative: arrow-key handlers, move-up/move-down buttons, or an aria-controlled reorder dialog. Drag and drop should enhance, not replace.

Disabling Browser Defaults

Text selection inside draggable elements can interfere with the drag. Apply CSS user-select: none and -webkit-user-drag: element on the source so the browser drags the element rather than selecting the text inside it.

Knowledge Check

Why must you usually attach a dragstart listener even though the draggable="true" attribute alone makes an element draggable?

Summary

Mark sources with draggable="true" and use dragstart to populate dataTransfer, set effectAllowed and optionally a custom drag image. Pair with dragend to clean up styles. Provide keyboard alternatives for accessibility and consider polyfills for touch.

Frequently asked questions

Is the “draggable Attribute and dragstart Event” lesson free?

Yes — the full text of “draggable Attribute and dragstart Event” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.

What will I learn in “draggable Attribute and dragstart Event”?

Make elements draggable and respond to dragstart. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start HTML Academy?

No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “draggable Attribute and dragstart Event” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this HTML Academy lesson?

Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. draggable Attribute and dragstart Event
  2. dragover and drop Events
  3. dataTransfer Object
  4. Practical Drag-to-Reorder List
← Back to HTML Academy