HTML Tutorial menu

HTML Drag and Drop

With the Drag and Drop API, users can pick up an element with the mouse and drop it somewhere else on the page.

How Drag and Drop Works

Every drag has two sides:

  1. The draggable element, the thing the user picks up.
  2. The drop zone, the place where it can be dropped.
EventFires onWhen
dragstartThe dragged elementThe user starts dragging
dragendThe dragged elementThe drag finishes (dropped or cancelled)
dragenterThe drop zoneThe dragged item enters it
dragoverThe drop zoneAgain and again while the item is over it
dragleaveThe drop zoneThe item leaves it
dropThe drop zoneThe user lets go over it

Step 1: Make an Element Draggable

Links and images can be dragged by default. For anything else, add draggable="true":

Example

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

Step 2: Remember What Is Dragged

In dragstart, save the element's id in dataTransfer. This is the "luggage" that travels with the drag.

Example

javascript
card.addEventListener("dragstart", function (event) {
  event.dataTransfer.setData("text/plain", event.target.id);
});

Step 3: Allow Dropping

By default, elements refuse drops. You must call event.preventDefault() in the dragover event to say "dropping here is allowed".

Example

javascript
zone.addEventListener("dragover", function (event) {
  event.preventDefault();
});

Forgetting preventDefault() in dragover is the most common drag and drop mistake. Without it, the drop event never fires.

Step 4: Handle the Drop

Example

javascript
zone.addEventListener("drop", function (event) {
  event.preventDefault();
  const id = event.dataTransfer.getData("text/plain");
  zone.appendChild(document.getElementById(id));
});

appendChild moves the element into the drop zone.

A Complete Example

Drag the fruit into the basket.

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
  .item { display: inline-block; padding: 8px 14px; margin: 4px; background: #ffe7a3;
          border-radius: 6px; cursor: grab; }
  #basket { min-height: 80px; margin-top: 16px; padding: 10px; border: 3px dashed #999;
            border-radius: 8px; }
  #basket.over { border-color: #e34c26; background: #fff3f0; }
</style>
</head>
<body>

<div>
  <span class="item" id="mango" draggable="true">Mango</span>
  <span class="item" id="banana" draggable="true">Banana</span>
  <span class="item" id="apple" draggable="true">Apple</span>
</div>

<div id="basket">Basket: drop fruit here</div>
<p id="msg"></p>

<script>
const basket = document.getElementById("basket");

document.querySelectorAll(".item").forEach(function (item) {
  item.addEventListener("dragstart", function (event) {
    event.dataTransfer.setData("text/plain", item.id);
  });
});

basket.addEventListener("dragover", function (event) {
  event.preventDefault();
  basket.classList.add("over");
});

basket.addEventListener("dragleave", function () {
  basket.classList.remove("over");
});

basket.addEventListener("drop", function (event) {
  event.preventDefault();
  basket.classList.remove("over");
  const id = event.dataTransfer.getData("text/plain");
  basket.appendChild(document.getElementById(id));
  document.getElementById("msg").innerHTML = "You added " + id + " to the basket.";
});
</script>

</body>
</html>
Try it Yourself »

The over class colours the basket while something is above it, so the user can see where the drop will land.

A Simple Task Board

The same idea builds a "To do / Done" board, like the ones used to plan projects. Each column is a drop zone.

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
  .board { display: flex; gap: 12px; }
  .col { flex: 1; min-height: 150px; padding: 8px; background: #f1f1f1; border-radius: 8px; }
  .task { padding: 8px; margin: 6px 0; background: white; border: 1px solid #ccc;
          border-radius: 6px; cursor: grab; }
</style>
</head>
<body>

<div class="board">
  <div class="col" id="todo">
    <h3>To do</h3>
    <div class="task" id="t1" draggable="true">Write HTML page</div>
    <div class="task" id="t2" draggable="true">Add CSS styles</div>
  </div>
  <div class="col" id="done">
    <h3>Done</h3>
  </div>
</div>

<script>
document.querySelectorAll(".task").forEach(function (task) {
  task.addEventListener("dragstart", function (e) {
    e.dataTransfer.setData("text/plain", task.id);
  });
});

document.querySelectorAll(".col").forEach(function (col) {
  col.addEventListener("dragover", function (e) { e.preventDefault(); });
  col.addEventListener("drop", function (e) {
    e.preventDefault();
    col.appendChild(document.getElementById(e.dataTransfer.getData("text/plain")));
  });
});
</script>

</body>
</html>
Try it Yourself »

Dropping Files from the Computer

A drop zone can also receive files dragged from the desktop. They arrive in event.dataTransfer.files:

Example

javascript
zone.addEventListener("drop", function (event) {
  event.preventDefault();
  const file = event.dataTransfer.files[0];
  zone.innerHTML = "You dropped: " + file.name + " (" + file.size + " bytes)";
});

Things to Keep in Mind

  • The HTML Drag and Drop API works with a mouse. On most phones, touch dragging needs extra code or a library.
  • Some users cannot use a mouse. Always give another way too, such as a button "Move to Done".

Exercise

Exercise

Your drop event never fires. What is the most likely reason?

Learn HTML with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp