W3docs

HTML draggable Attribute

The HTML draggable attribute is an enumerated attribute and specifies whether the element is draggable or not. Read and see on what elements it can be used.

The HTML draggable attribute is an enumerated attribute that specifies whether an element can be dragged by the user with a pointing device (mouse or touch). It is the entry point to the HTML Drag and Drop API, which lets you move elements, text, files, or custom data from one place in a page to another.

Setting draggable="true" only makes an element pickable. To actually move something and drop it somewhere useful, you also need to handle the drag-and-drop events and carry information through the dataTransfer object — both covered below.

You can use this attribute on any HTML element. It is a part of the Global Attributes, so it works alongside other global attributes such as contenteditable.

Values

The draggable attribute can have the following values:

  • true — the element can be dragged.
  • false — the element cannot be dragged. Useful for disabling the default dragging of images and links.
  • auto — use the browser's default behavior for that element. In practice this means images and links are draggable, and most other elements are not. Because auto simply defers to the default, it is rarely written explicitly; omitting draggable gives the same result.
<tag draggable="true|false|auto"></tag>

Note: draggable is not a boolean attribute. You must write the value explicitly — draggable on its own or draggable="" is invalid. Always use draggable="true" or draggable="false".

How drag and drop works

A drag-and-drop interaction fires a sequence of events, split between the element being dragged (the source) and the element it is dropped on (the target):

EventFires onWhen
dragstartsourceThe user starts dragging the element. Set your data here with dataTransfer.setData().
dragsourceRepeatedly while the element is being dragged.
dragentertargetThe dragged element enters a valid drop target.
dragovertargetRepeatedly while the element is over a drop target. Call preventDefault() here.
dragleavetargetThe dragged element leaves the drop target.
droptargetThe element is released over the target. Read your data here with dataTransfer.getData().
dragendsourceThe drag ends (whether it was dropped successfully or cancelled).

The dataTransfer object

Every drag event exposes event.dataTransfer, the channel used to pass data from the source to the target:

  • event.dataTransfer.setData(format, data) — store a string during dragstart. The format is usually a MIME type like "text/plain" (older code uses "Text", which still works).
  • event.dataTransfer.getData(format) — read that string back during drop.

Because data only becomes available on drop, the typical pattern is to store an element's id (or any identifier) in dragstart, then look it up and move it in drop.

Why preventDefault() is required

By default, most elements are not valid drop targets, so the browser cancels the drop. To opt an element in as a drop zone you must call event.preventDefault() in its dragover handler — this tells the browser "yes, a drop is allowed here." It is also common to call preventDefault() in the drop handler to stop the browser's default action (for example, navigating to a dragged link or opening a dropped file).

If you forget preventDefault() in dragover, the drop event never fires and nothing happens.

Example (inline handlers)

This example uses inline event-handler attributes (ondragstart, ondragover, ondrop). It is concise but mixes JavaScript into the markup:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      #rectId {
        width: 350px;
        height: 70px;
        padding: 10px;
        border: 1px solid #aaaaaa;
      }
    </style>
    <script>
      function allowDrop(event) {
        event.preventDefault(); // Allow dropping
      }
      function drag(event) {
        // Store the dragged element's ID in the dataTransfer object
        event.dataTransfer.setData("text/plain", event.target.id);
      }
      function drop(event) {
        event.preventDefault();
        var data = event.dataTransfer.getData("text/plain"); // Retrieve the ID
        event.target.appendChild(document.getElementById(data));
      }
    </script>
  </head>
  <body>
    <div id="rectId" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <br />
    <p id="dragId" draggable="true" ondragstart="drag(event)">
      This is a draggable paragraph. Drag this item to the rectangle.
    </p>
  </body>
</html>

Example (modern addEventListener)

For maintainable code, keep the markup clean and attach handlers in JavaScript with addEventListener. This is the recommended approach:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      #dropzone {
        width: 350px;
        height: 70px;
        padding: 10px;
        border: 1px solid #aaaaaa;
      }
    </style>
  </head>
  <body>
    <div id="dropzone"></div>
    <br />
    <p id="item" draggable="true">
      This is a draggable paragraph. Drag this item to the rectangle.
    </p>

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

      // Source: store the dragged element's ID when the drag begins.
      item.addEventListener("dragstart", (event) => {
        event.dataTransfer.setData("text/plain", event.target.id);
      });

      // Target: allow dropping by preventing the default handling.
      dropzone.addEventListener("dragover", (event) => {
        event.preventDefault();
      });

      // Target: move the element into the drop zone.
      dropzone.addEventListener("drop", (event) => {
        event.preventDefault();
        const id = event.dataTransfer.getData("text/plain");
        const dragged = document.getElementById(id);
        event.currentTarget.appendChild(dragged);
      });
    </script>
  </body>
</html>

Accessibility

The draggable attribute provides no keyboard or screen-reader support on its own — drag and drop is a pointer-only interaction. Users who navigate by keyboard or assistive technology cannot perform a native drag.

If drag and drop is the only way to complete an action, always offer an accessible alternative (for example, "Move up / Move down" buttons, a select menu, or copy/paste). Treat native drag and drop as an enhancement, not the sole path.

Practice

Practice
What is true about the HTML draggable attribute?
What is true about the HTML draggable attribute?
Was this page helpful?