Drag to Reorder List
Sortable task list with a smooth drag-and-drop reorder, spring settle and tick-off circles. Pointer events, no libraries.
Preview and code
index.html
<div class="so"><div class="hd"><span>IN THE STUDIO</span><b>Make room for what matters.</b></div><div class="sl"></div></div>
styles.css
.so{width:100%;height:100%;min-height:380px;box-sizing:border-box;padding:24px;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:system-ui,-apple-system,sans-serif;color:#eee;}.hd{width:340px;margin-bottom:14px}.hd span{display:block;font-size:10px;letter-spacing:.14em;color:#777}.hd b{font-size:16px}.sl{position:relative;width:340px;height:264px}.it{position:absolute;left:0;right:0;height:58px;background:#1b1b1b;border:1px solid #2a2a2a;border-radius:14px;display:flex;align-items:center;gap:10px;padding:0 12px;box-sizing:border-box;cursor:grab;touch-action:none;user-select:none;transition:transform .3s cubic-bezier(.3,1.3,.5,1),box-shadow .2s}.it.dr{transition:box-shadow .2s;box-shadow:0 12px 30px rgba(0,0,0,.5);z-index:3;cursor:grabbing;border-color:#0a84ff}.ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;font-size:13px;color:#fff}.tx b{display:block;font-size:13px}.tx small{font-size:11px;color:#777}.ck{margin-left:auto;width:16px;height:16px;border-radius:50%;border:1.5px solid #444;display:grid;place-items:center;font-size:10px;cursor:pointer}.ck.on{background:#0a84ff;border-color:#0a84ff}
script.js
(function(){var L=document.querySelector(".sl"),H=66;var I=[["Collect references","Find the right direction","#b7791f","1"],["Explore the visual system","Type, color, and composition","#b83280","2"],["Build the first prototype","Make the interaction tangible","#2b6cb0","3"],["Ship something useful","Polish the details and release","#2f855a","4"]];var els=I.map(function(d){var e=document.createElement("div");e.className="it";e.innerHTML="<span class=\"ic\" style=\"background:"+d[2]+"\">"+d[3]+"</span><span class=\"tx\"><b>"+d[0]+"</b><small>"+d[1]+"</small></span><span class=\"ck\"></span>";L.appendChild(e);return e});var order=els.slice();function pos(skip){order.forEach(function(e,i){if(e!==skip)e.style.transform="translateY("+i*H+"px)"})}pos();els.forEach(function(e){e.querySelector(".ck").onclick=function(ev){ev.stopPropagation();this.classList.toggle("on");this.textContent=this.classList.contains("on")?"✓":""};e.querySelector(".ck").onpointerdown=function(ev){ev.stopPropagation()};e.onpointerdown=function(ev){var idx=order.indexOf(e),sy=ev.clientY;e.setPointerCapture(ev.pointerId);e.classList.add("dr");function mv(m){var y=Math.max(0,Math.min(3*H,idx*H+m.clientY-sy));e.style.transform="translateY("+y+"px) scale(1.02)";var t=Math.round(y/H);var rest=order.filter(function(x){return x!==e});rest.splice(t,0,e);order=rest;pos(e)}function up(){e.removeEventListener("pointermove",mv);e.removeEventListener("pointerup",up);e.classList.remove("dr");pos()}e.addEventListener("pointermove",mv);e.addEventListener("pointerup",up)}})})();