Source Code

<div class="dr-wrap">
  <h2 class="dr-heading">Priority List</h2>
  <p class="dr-sub">Drag items to reorder them.</p>
  <ul class="dr-list" id="drList"></ul>
</div>

Drag to Reorder Priority List — Free HTML CSS JS Snippet

Drag to Reorder Priority List · Misc · Plain HTML, CSS & JS · Live preview

What's included

Features

Native HTML5 drag-and-drop API with draggable, dragstart, dragover, drop, and dragend handlers
Live dashed placeholder shows exactly where the dragged item will land as the cursor moves
getDragAfterElement midpoint calculation determines insertion position from cursor Y coordinate
Numeric rank badges automatically renumber after every reorder
Faded opacity on the actively dragged item for clear visual feedback
Drag handle icon signals the draggable affordance without extra libraries
Fully self-contained vanilla JS with no external dependencies

About this UI Snippet

Drag to Reorder Priority List — HTML5 Drag-and-Drop With Live Placeholder

Screenshot of the Drag to Reorder Priority List snippet rendered live

This snippet is a draggable priority list: six items that can be reordered by drag and drop, built entirely on the native HTML5 drag-and-drop API rather than a library like Sortable.js.

Tracking the dragged element

Every list item is draggable="true". On dragstart, the item is stored in a module-level dragEl variable and given a .dr-dragging class (added on a setTimeout(…, 0) so the drag ghost image is captured before the opacity change applies). dragend clears both the class and dragEl, and removes any leftover placeholder.

Computing drop position with getDragAfterElement

The interesting part is figuring out *where* the dragged item would land. dragover on the list computes the vertical midpoint of every other item and picks the first one whose midpoint is below the cursor's y position — this is the classic "get element after which to insert" technique. A dashed placeholder <li> is then inserted right at that computed position, giving the user a live visual preview of where the item will drop before they let go.

Committing the reorder on drop

The drop handler simply moves the actual dragged DOM node to where the placeholder currently sits, then removes the placeholder. Because the placeholder was already tracking the correct insertion point throughout the drag, the drop itself is just one DOM move. After every drag ends, renderRanks() walks the list and rewrites each item's numeric rank badge to match its new position.

Step by step

How to Use

  1. 1
    Load the snippetClick "Drag to Reorder Priority List" in the sidebar to load its HTML, CSS, and JS into the editor panels. The preview updates instantly.
  2. 2
    Edit the codeModify any panel — HTML, CSS, or JS. The preview refreshes as you type. Use Reset in each panel header to restore the original.
  3. 3
    Preview on devicesClick the Mobile (375px), Tablet (768px), or Desktop buttons in the preview header to check responsiveness.
  4. 4
    Export in your formatClick "HTML" to download a standalone file, "JSX" for a React component, "Tailwind" for a React + Tailwind CSS component, "Tailwind HTML" for a standalone HTML file with Tailwind CDN, "Vue" for a Vue 3 SFC with <template>/<script setup>/<style scoped>, or "Angular" for a standalone Angular .component.ts file. "Copy all" copies the full code to clipboard.
  5. 5
    Save your versionClick "Save as", type a name, and press Enter. Your snippet saves to IndexedDB and appears in the Saved tab.

Real-world uses

Common Use Cases

Task and priority managers
Let users manually rank todos, backlog items, or priorities by dragging.
Reference for placeholder-based drag reordering
A clean implementation of the getDragAfterElement pattern used by many reorderable-list libraries.
Settings and preference ordering
Reorder notification channels, dashboard widgets, or menu items by drag.
Teaching HTML5 drag-and-drop internals
Demonstrates dataTransfer, midpoint-based insertion, and placeholder-driven UX without a library.

Got questions?

Frequently Asked Questions

The dragover handler measures the bounding rectangle of every non-dragging item, compares the cursor Y position against each item's vertical midpoint, and inserts the placeholder immediately before the first item whose midpoint sits below the cursor.

The drop handler moves the real dragged <li> element to the placeholder's position, so it is an actual DOM reorder, not a purely visual illusion.

Some browsers capture the drag ghost image synchronously when dragstart fires. Adding the opacity-reducing class immediately would make the ghost image itself appear faded; deferring it by one tick lets the ghost snapshot the original appearance.

Yes, the ITEMS array can hold any number of strings — the placeholder and rank-numbering logic scale to any list length without changes.