I Built a Drag-and-Drop Kanban Board with Vanilla JavaScript
If you've ever wanted to understand how drag-and-drop actually works under the hood — no libraries, no frameworks, just the browser — building a Kanban board is a great way to find out. Here's how I built one using plain HTML, CSS, and JavaScript. The Idea A Kanban board is one of those projects that looks simple on the surface but forces you to actually understand the DOM: creating elements,…
Creating a drag-and-drop Kanban board with just plain HTML, CSS, and JavaScript is a fantastic way to gain a deeper understanding of how the browser's native Drag and Drop API actually functions. In this project, we end up with three columns — To Do, In Progress, and Done — where cards can be moved easily between them. The structure is simple, featuring a `.board` container containing three `.list` columns.
Each column is associated with a heading and a few `.card` elements that have the `draggable="true"` attribute, unlocking the HTML5 Drag and Drop API.
The core functionality relies on several key events tied to both the cards and the lists. For each card, we listen for the `dragstart` and `dragend` events. When a drag begins, the card's ID is stored in the `dataTransfer` object. This single piece of data serves as our state, as all other information can be retrieved from the DOM.
On each list, we handle the `dragover`, `dragenter`, `dragleave`, and `drop` events. The `dragover` event is essential as it must call `preventDefault()`. This call is crucial because browsers block drops by default, and invoking `preventDefault()` tells the browser that the element accepts drops. Following this, the `dragDrop` function retrieves the card's ID from the `dataTransfer` object and appends it to the list using `appendChild()`.
This move is seamless, as the card is simply relocated to a new parent node without any cloning or re-rendering required.
To enhance the user experience, a subtle `.over` class is added, which activates during `dragenter` and `dragleave` events, giving the target list a faint highlight. This small detail makes the board feel more responsive. A further enhancement could be persistence, allowing the board state to be saved with `localStorage` so that cards persist between page refreshes.
Adding the ability to create, edit, and delete cards directly within the board could also be valuable. Finally, adding touch support could make the board more versatile for mobile users, although the native Drag and Drop API may require a fallback for optimal mobile compatibility.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.