Source Code

<div class="pmb-card">
  <div class="pmb-head">
    <h3>Priority matrix</h3>
    <span>Drag tasks between quadrants</span>
  </div>
  <div class="pmb-axis-label pmb-axis-top">Important</div>
  <div class="pmb-grid">
    <div class="pmb-quad" data-q="do" style="--c:#22c55e">
      <div class="pmb-quad-head">Do first <span>Urgent + Important</span></div>
      <div class="pmb-list" data-q="do"></div>
    </div>
    <div class="pmb-quad" data-q="schedule" style="--c:#6366f1">
      <div class="pmb-quad-head">Schedule <span>Not urgent + Important</span></div>
      <div class="pmb-list" data-q="schedule"></div>
    </div>
    <div class="pmb-quad" data-q="delegate" style="--c:#f59e0b">
      <div class="pmb-quad-head">Delegate <span>Urgent + Not important</span></div>
      <div class="pmb-list" data-q="delegate"></div>
    </div>
    <div class="pmb-quad" data-q="delete" style="--c:#94a3b8">
      <div class="pmb-quad-head">Delete <span>Not urgent + Not important</span></div>
      <div class="pmb-list" data-q="delete"></div>
    </div>
  </div>
  <div class="pmb-axis-label pmb-axis-bottom">Urgent</div>
</div>

Priority Matrix Board — Eisenhower Drag-and-Drop

Priority Matrix Board · Layouts · Plain HTML, CSS & JS · Live preview

What's included

Features

Four real drop targets
Every quadrant is an independent native HTML5 drop zone, all driven by the same shared, generic drag/drop handlers.
Single source of truth per task
A task's quadrant is one field (q) on a shared array, eliminating the risk of duplicate or lost tasks during a move.
Color-coded quadrant priority
Each quadrant's accent color (green, indigo, amber, gray) visually reinforces its urgency/importance combination.
Empty-quadrant-safe drop highlighting
The entire list area highlights on drag-over, not just existing cards, so empty quadrants are still valid, visible drop targets.
Re-render from filtered data
Each quadrant's visible tasks are simply TASKS filtered by quadrant — no manual DOM node moving between containers.
Axis labels for framework context
"Important" and "Urgent" axis labels frame the four quadrants within the actual Eisenhower Matrix logic.
Lightweight, dependency-free drag-and-drop
Built entirely on native browser drag events — no sorting library needed for a multi-container board.
Easy to extend with more metadata
Each task object can carry additional fields (due date, assignee) without changing the core quadrant-filtering logic.

About this UI Snippet

Priority Matrix Board — Eisenhower Quadrants with Native Drag-and-Drop Tasks

Screenshot of the Priority Matrix Board snippet rendered live

The Eisenhower Matrix — sorting work into Urgent/Important, Important/Not Urgent, Urgent/Not Important, and neither — is one of the most widely taught prioritization frameworks precisely because the four-quadrant layout makes "what should I actually work on" visually obvious in a way a flat to-do list never can. This snippet builds the matrix as a real drag-and-drop board: four labeled quadrants, each a native drop target, holding draggable task cards that move freely between them.

Four drop zones, one shared drag implementation

Every quadrant's task list is an independent native HTML5 drop target wired to the same three events (dragover, dragleave, drop), and every task card is a draggable element wired to dragstart/dragend — the same underlying API used by this library's image reorder grid, applied here across multiple distinct containers instead of within a single grid. Because the drop handler only needs to know *which quadrant* it belongs to (read from list.dataset.q), the same generic logic handles all four zones without four separate near-duplicate handlers.

A task's quadrant is a property, not a list membership

Rather than storing four separate arrays (one per quadrant) and physically moving an object between them, every task has a single q field holding its current quadrant id, and render() simply filters the one shared TASKS array by quadrant for each list. Dropping a task onto a new quadrant is therefore a one-line mutation (task.q = list.dataset.q) followed by a full re-render — there's no risk of a task accidentally existing in two lists at once or vanishing during a move, a real bug class with the multi-array approach.

Color-coded quadrant headers reinforce the framework

Each quadrant has a colored top border and label pair — "Do first" in green for urgent-and-important, "Schedule" in indigo, "Delegate" in amber, "Delete" in gray — set via a CSS custom property (--c) per quadrant, so the visual hierarchy (green = act now, gray = least important) reads correctly even before a user reads the quadrant's full description text.

Drop-target highlighting per list

Hovering a dragged task over any quadrant's list (not just over an existing task) highlights that entire list with a subtle tinted background via .drag-over — crucial for an empty quadrant, which has no task cards to hover over but still needs to show it's a valid drop target.

The matrix forces a decision a flat list avoids

A plain to-do list lets "urgent-feeling but unimportant" busywork sit at the same visual level as the one task that actually matters, because nothing forces you to weigh importance against urgency before adding an item. The matrix's four labeled quadrants make that judgment call unavoidable at the moment a task is placed (or dragged elsewhere), which is the entire reason this 1950s framework still gets taught in every productivity course written since.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to work out the shared drag-and-drop wiring by hand. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why every task's quadrant is stored as a single q field on one shared array instead of four separate arrays, and how that design choice makes the generic dragover/drop handlers safe against a task ending up duplicated or lost during a move. The same assistant can help optimize it, for example checking whether re-rendering all four quadrant lists on every single drop is wasteful once the task count grows large, or whether the drag-over highlight logic correctly handles a fast drag that crosses multiple quadrants quickly. It's also useful for extending the effect: ask it to add within-quadrant reordering (not just moving between quadrants), persist each task's quadrant to a backend after every drop, or add touch event support since native HTML5 drag-and-drop has inconsistent mobile behavior. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an Eisenhower Matrix priority board with drag-and-drop tasks in plain HTML, CSS, and vanilla JavaScript using the native HTML5 Drag and Drop API — no sorting library.

Requirements:
- A 2x2 grid of four labeled quadrants (for example Do first, Schedule, Delegate, Delete), each with its own accent color and a short description of what urgency/importance combination it represents, plus axis labels framing the grid (Important on one side, Urgent on the other).
- A single shared array of task objects, where each task has a unique id, a text label, and one field indicating which quadrant it currently belongs to — do not use four separate arrays, one per quadrant.
- Render each quadrant's visible tasks by filtering the one shared array down to tasks whose quadrant field matches that quadrant's id, re-rendering all four lists together whenever the underlying data changes.
- Make every task element draggable using the native draggable attribute and dragstart/dragend events (fading and slightly shrinking the element while it's being dragged), and make every quadrant's task-list container a valid drop target using dragover (with preventDefault so drop is allowed), dragleave, and drop events — implemented once generically so the same handler logic works for all four quadrants by reading which quadrant a list belongs to from a data attribute.
- On a successful drop, update only the single quadrant field on the dropped task's object (not any array membership), then re-render every quadrant's filtered list.
- While dragging over any quadrant's list area, highlight that entire list container (not just individual task cards) with a distinct background tint, so even an empty quadrant is visibly a valid drop target, and remove the highlight when the drag leaves or completes.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA 2×2 matrix renders with "Important" and "Urgent" axis labels and eight example tasks distributed across the four quadrants.
  2. 2
    Drag a taskClick and hold any task card — it fades and shrinks slightly to show it's being dragged.
  3. 3
    Hover a different quadrantThat quadrant's task list highlights with a tinted background, even if it's currently empty.
  4. 4
    Drop the taskRelease over the target quadrant — the task moves there instantly and both quadrants' lists update.
  5. 5
    Add your own tasksPush a new { id, text, q } object into the TASKS array and call render() to add it to the matrix in its starting quadrant.
  6. 6
    Persist quadrant assignmentsAfter a drop, send each task's id and updated q value to your backend so the matrix layout survives a page reload.

Real-world uses

Common Use Cases

Personal task and time management
The classic individual productivity use of the Eisenhower Matrix for daily or weekly planning.
Team sprint and triage planning
Sort incoming requests or bugs into urgency/importance quadrants during a planning or triage meeting.
Product and feature prioritization
Relabel quadrants as Impact/Effort and use the same drag-and-drop matrix for a feature prioritization workshop.
Project management tool integrations
Offer a matrix view alongside a Kanban board as an alternate way to triage the same task list.
Coaching and productivity apps
Teach the Eisenhower framework interactively rather than as a static diagram.
Learning multi-container drag-and-drop
A clear example of one generic drop handler serving several distinct containers — pair with a drag-sort list for a single-list variant.

Got questions?

Frequently Asked Questions

In the drop handler, after task.q is updated, send that task's id and new q value to your backend with a fetch PATCH call, so reloading the page can restore each task to its last-dropped quadrant instead of resetting to the static TASKS array.

Track a drop position within the target list (similar to the index-based splice logic in the image reorder grid snippet) in addition to the quadrant change, and insert the dragged task at that specific position in a quadrant-filtered, order-preserving array rather than just appending it.

Add the fields to each task object (e.g. due, assignee) and extend the template string in render() to display them on the card — the filtering and drag-and-drop logic doesn't need to change since it only depends on the q field.

The native HTML5 Drag and Drop API has inconsistent touch support; add touchstart/touchmove/touchend listeners that track the dragged card's position and manually detect which quadrant's bounding box the finger is over on release, calling the same task.q update and render() used by the desktop drop handler.

In React, keep tasks in useState and update a task's q on drop via setTasks with a mapped array; in Vue, mutate a reactive tasks array directly; in Angular, use a component array field updated the same way. Filtering tasks per quadrant for rendering is a simple .filter() call in every framework's templating syntax.