Labs ICT
Pro Login

Drag & Drop

Drag and drop is one of those interactions that feels so natural — you grab something and move it somewhere else. HTML5 gives you a built-in Drag and Drop API that lets you make elements draggable and define where they can be dropped. Let us break down how it works.

Making an Element Draggable

To make any element draggable, add the draggable="true" attribute to it. This tells the browser that the element can be picked up and dragged around. Without this attribute, dragging does nothing.


<div draggable="true" id="dragItem">Drag me!</div>
<div id="dropZone">Drop here</div>
    

The Drag Events

The API uses several events to track the drag process. dragstart fires when you start dragging. drag fires while the element is being dragged. dragend fires when the drag ends — whether the element was dropped on a valid target or not.


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

  dragItem.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', e.target.id);
    e.target.style.opacity = '0.5';
  });

  dragItem.addEventListener('dragend', (e) => {
    e.target.style.opacity = '1';
  });
</script>
    

The Drop Events

Drop targets listen for dragenter, dragover, dragleave, and drop. The most important one is dragover — you must call e.preventDefault() on it to allow dropping. Without that, the browser blocks the drop.


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

  dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
    dropZone.style.background = '#d0ffd0';
  });

  dropZone.addEventListener('dragleave', () => {
    dropZone.style.background = '';
  });

  dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text/plain');
    dropZone.appendChild(document.getElementById(id));
    dropZone.style.background = '';
  });
</script>
    

Visual Feedback During Drag

Good drag and drop gives the user visual feedback. You can use setDragImage() to customize what the dragged ghost image looks like, or simply change the opacity and background colors as items are dragged over valid drop zones.


<style>
  #dragItem {
    padding: 16px;
    background: #3b82f6;
    color: white;
    cursor: grab;
    border-radius: 8px;
  }
  #dropZone {
    min-height: 100px;
    border: 2px dashed #999;
    margin-top: 16px;
    padding: 16px;
    border-radius: 8px;
  }
</style>