Full technical and architectural documentation of the Kanban Board task management app.
← Back to BoardKanban Board is a lightweight, purely client-side task management application built with vanilla HTML, CSS, and JavaScript. It provides a familiar three-column workflow — To Do, In Progress, Done — letting users organize tasks through intuitive drag-and-drop, with zero backend dependency.
The project focuses on proving that a genuinely useful, persistent productivity tool can be built with no frameworks, no build step, and no database — just the browser.
Kanban Board aims to deliver a fast, no-setup task tracker that works entirely offline-capable in the browser, demonstrating clean vanilla-JS architecture without relying on any external libraries or frameworks.
Kanban Board delivers instant usability and high performance with zero dependencies — no backend, no database, no build tools — by treating the DOM itself as the single source of truth and syncing state from it directly.
| Markup | HTML5 — semantic structural tags with fixed column containers |
| Styling | Vanilla CSS — CSS Custom Properties (:root variables) + Flexbox layout |
| Scripting | Vanilla JavaScript (ES6) — global script, native DOM APIs, no modules/IIFEs |
| External Assets | Google Fonts (Quicksand) — no JS libraries or CSS frameworks used |
| Data Persistence | Browser localStorage (single JSON blob, key: tasks) |
| Hosting | Static file deployment — no build step, no bundler |
Built entirely on the native HTML5 Drag & Drop API (draggable, dragenter, dragleave, dragover, drop) — deliberately bypassing the native dataTransfer object in favor of a single global reference (dragElement) that tracks the currently dragged node. Dropped tasks are appended to the bottom of the target column; visual feedback is handled via a .hover-over class that scales the column (1.02x) and applies a dashed border on dragenter.
Rather than the conventional "update state → re-render DOM" flow, this app inverts it: the DOM action happens first, then the entire tasksData object is rebuilt by querying the live DOM for every column's current tasks. This guarantees the saved state always matches exactly what the user sees, with no drift between UI and data.
Every state-changing action (add, drag-drop, delete) synchronously serializes tasksData to localStorage under the tasks key — no debouncing, no batching. On page load, the saved JSON is parsed and the DOM is rehydrated node-by-node via document.createElement.
Tasks carry no unique IDs, timestamps, or status fields in their data — status is implied entirely by which column's array they live in. Deletion uses a single delegated click listener on the document, locating the parent task node and triggering a scoped rebuild of just that column's state.
Hover over each structure to reveal its shape (no database — this is the in-memory + localStorage JSON structure).
Top-level object keyed by column ID (todo, progress, done), each mapping to an array of tasks.
{
"todo": [ ... ],
"progress": [ ... ],
"done": [ ... ]
}
Minimal shape — just title and description. No ID, timestamp, or status field; position and parent column imply everything.
{
"title": "Fix bug",
"description": "Details about bug..."
}
Script and stylesheet are linked conventionally — CSS in <head>, JS via a single <script> tag just before </body>.
Layout is Flexbox-driven throughout: a full-height flex column wraps the app, the board section is a flex row with flex-grow: 1, and each column is an internal flex column with consistent gaps. No media queries are implemented — the layout targets desktop viewports.
The "Add Task" modal is a custom div-based overlay (not native <dialog>), using backdrop-filter: blur(10px) over an rgba background for a glassmorphism effect behind a solid modal panel. Drag transitions use a soft cubic-bezier(0.19,1,0.22,1) easing curve for a fluid, weighted feel. Delete buttons carry a subtle red tint and sit flush to the bottom-right of each card via align-self: flex-end.
| Hosting | Static raw file deployment — no host-specific config detected |
| Build Step | None — no package.json, bundler, or transpiler required |
| Live URL | Not present in codebase comments or config |