</>
Skip to content
HTML lessons (50/60)

HTML — Drag and Drop

Friendly Introduction: What & Why

Drag and drop lets people pick an item with the mouse, move it, and drop it somewhere else.
It feels natural on a computer, and you can use it for file uploads, rearranging lists, or building simple games.
In this lesson you’ll see the tiny bits of JavaScript that make the browser understand the drag action.
You’ll also learn how to style the drag target and the drop zone so the user knows what’s happening.


Basics of Drag and Drop

The browser sends four main events when a drag happens:

EventWhen it firesTypical use
dragstartWhen the user begins draggingSet the data to send
dragoverWhile the item is over a drop targetAllow the drop by preventing default
dropWhen the user releases the itemRead the data and do something
dragendAfter the drop or cancelClean up styles

Below is the simplest example: a red square you can drag into a blue box.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Basic Drag and Drop</title>
<style>
  #dragme { width: 100px; height: 100px; background: red; cursor: grab; }
  #dropzone { width: 120px; height: 120px; background: lightblue; margin-top: 20px; }
</style>
</head>
<body>

<div id="dragme" draggable="true">Drag me</div>
<div id="dropzone">Drop here</div>

<script>
const dragItem = document.getElementById('dragme');
const dropZone = document.getElementById('dropzone');

dragItem.addEventListener('dragstart', e => {
  e.dataTransfer.setData('text/plain', 'red square');
});

dropZone.addEventListener('dragover', e => e.preventDefault()); // allow drop
dropZone.addEventListener('drop', e => {
  e.preventDefault();
  dropZone.textContent = 'Dropped!';
});
</script>

</body>
</html>

What the browser displays

  • A red square labeled “Drag me” and a light‑blue rectangle that says “Drop here.”
  • When you drag the red square over the blue rectangle, nothing changes visually.
  • Releasing the mouse inside the rectangle changes its text to “Dropped!”.

Setting Data Transfer

You can send any string or even a reference to an image.
Here we drag a word and a picture.

<div id="dragword" draggable="true">Hello</div>
<img id="dragimg" src="https://picsum.photos/80" draggable="true" alt="Random image">

<div id="dropzone2">Drop word or image here</div>

<script>
const word = document.getElementById('dragword');
const img = document.getElementById('dragimg');
const drop2 = document.getElementById('dropzone2');

word.addEventListener('dragstart', e => {
  e.dataTransfer.setData('text/plain', e.target.textContent);
});

img.addEventListener('dragstart', e => {
  e.dataTransfer.setData('text/uri-list', e.target.src);
});

drop2.addEventListener('dragover', e => e.preventDefault());
drop2.addEventListener('drop', e => {
  e.preventDefault();
  const text = e.dataTransfer.getData('text/plain');
  const url = e.dataTransfer.getData('text/uri-list');
  if (text) drop2.textContent = `Word: ${text}`;
  else if (url) drop2.innerHTML = `<img src="${url}" alt="Dropped image">`;
});
</script>

What the browser displays

  • A word “Hello” and a small random image are draggable.
  • Dropping the word changes the drop zone to show “Word: Hello”.
  • Dropping the image replaces the drop zone’s content with the image itself.

Using CSS to Indicate Drop Target

A user often needs a visual cue that a drop zone accepts the item.
We add a border that appears when the dragged item hovers over it.

<div id="dragme2" draggable="true">Drag me 2</div>
<div id="dropzone3">Drop zone 3</div>

<script>
const drag2 = document.getElementById('dragme2');
const drop3 = document.getElementById('dropzone3');

drag2.addEventListener('dragstart', e => e.dataTransfer.setData('text/plain', 'item'));

drop3.addEventListener('dragover', e => e.preventDefault());
drop3.addEventListener('dragenter', () => drop3.style.border = '2px dashed green');
drop3.addEventListener('dragleave', () => drop3.style.border = 'none');
drop3.addEventListener('drop', e => {
  e.preventDefault();
  drop3.style.border = 'none';
  drop3.textContent = 'Received!';
});
</script>

What the browser displays

  • The drop zone shows a dashed green border only while the item is hovering over it.
  • Dropping the item removes the border and changes the text to “Received!”.

Advanced: Multiple Drop Zones

You can have many targets that accept different kinds of data.
In this example, one zone accepts text and another accepts images.

<div id="dragText" draggable="true">Text item</div>
<img id="dragImg" src="https://picsum.photos/60" draggable="true" alt="Pic">

<div id="textZone">Drop text here</div>
<div id="imgZone">Drop image here</div>

<script>
const textItem = document.getElementById('dragText');
const imgItem = document.getElementById('dragImg');
const textZone = document.getElementById('textZone');
const imgZone = document.getElementById('imgZone');

textItem.addEventListener('dragstart', e => e.dataTransfer.setData('text/plain', e.target.textContent));
imgItem.addEventListener('dragstart', e => e.dataTransfer.setData('text/uri-list', e.target.src));

[ textZone, imgZone ].forEach(z => z.addEventListener('dragover', e => e.preventDefault()));

textZone.addEventListener('drop', e => {
  e.preventDefault();
  const txt = e.dataTransfer.getData('text/plain');
  if (txt) textZone.textContent = `Got: ${txt}`;
});

imgZone.addEventListener('drop', e => {
  e.preventDefault();
  const url = e.dataTransfer.getData('text/uri-list');
  if (url) imgZone.innerHTML = `<img src="${url}" alt="Dropped">`;
});
</script>

What the browser displays

  • Two drop zones: one labeled “Drop text here” and the other “Drop image here”.
  • Dragging the text into the first zone updates its content.
  • Dragging the image into the second zone shows the image.

Good to know:
The draggable attribute is only true for elements that can be dragged.
For custom components, you may need to set draggable="true" on a wrapper element.


Common Mistakes Checklist

  • Forgetting draggable="true" on the element you want to move.
  • Not calling e.preventDefault() in the dragover handler, which blocks the drop.
  • Using text/plain for image data; it should be text/uri-list or a custom MIME type.
  • Not clearing styles in dragend or drop events, leaving the drop zone highlighted.
  • Trying to drop onto an element that doesn’t accept the data type you sent.

Mini Practice

  1. Create a list of three items. Make each item draggable and drop them into a single container that shows the item’s text.
  2. Add a second container that only accepts image files. Drag an image from your computer into the page (you can use a <input type="file"> to load it first) and drop it into the image container.
  3. Style the drop zones so they change background color when an item is hovering over them.
  4. Add a “Reset” button that clears all drop zones and restores the original items.
  5. Experiment with dataTransfer.effectAllowed and dropEffect to change the cursor icon during the drag.

Related Topics

Frequently Asked Questions about Drag and Drop

What is Drag and Drop in HTML?

Drag and Drop is a fundamental concept in HTML. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Drag and Drop?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Drag and Drop.

Why is Drag and Drop important in HTML?

Drag and Drop is essential for HTML development. Understanding this concept will help you write better code and solve real-world problems more effectively.