Mobile-First Drag and Drop Alternative for List Reordering – picknplace.js
Standard HTML5 drag and drop APIs are notoriously difficult to control on mobile devices. You might often accidentally scroll the page when you intend to move an item.
Picknplace.js addresses this by changing the interaction model. The user first “picks” an item (locks it), scrolls or moves to the desired location, and then “places” it. This ensures intentionality and prevents accidental UI shifts.
1. Download the picknplace.js library and import the createPickPlace function into your project:
import { createPickPlace } from "./picknplace.js"; 2. Initialize the library and attach it to your list elements:
// Create a new instance with default settings const pnp = createPickPlace(); // Initialize the pick-and-place functionality pnp.init();
3. Create the list structure. You need a container (list), items (list elements), and trigger buttons inside the items.
<ul class="pnp-list">
<li class="pnp-item">
<div class="item-content">
<div class="avatar">👨💻</div>
<div class="info">
<span class="name">Alex Chen</span>
<span class="role">Frontend Lead</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
<li class="pnp-item">
<div class="item-content">
<div class="avatar">👩🎨</div>
<div class="info">
<span class="name">Sarah Jones</span>
<span class="role">Product Designer</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
<li class="pnp-item">
<div class="item-content">
<div class="avatar">🚀</div>
<div class="info">
<span class="name">Mike Ross</span>
<span class="role">DevOps Engineer</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
<li class="pnp-item">
<div class="item-content">
<div class="avatar">💼</div>
<div class="info">
<span class="name">Jessica Wu</span>
<span class="role">Product Owner</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
<li class="pnp-item">
<div class="item-content">
<div class="avatar">🛡️</div>
<div class="info">
<span class="name">David Miller</span>
<span class="role">Security Specialist</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
<li class="pnp-item">
<div class="item-content">
<div class="avatar">📊</div>
<div class="info">
<span class="name">Emily Davis</span>
<span class="role">Data Scientist</span>
</div>
</div>
<div class="pnp-buttons">
<button class="pnp-pick btn-pick">Move</button>
</div>
</li>
</ul> 4. Create global controls to confirm or cancel the action.
<div class="pnp-controls"> <button class="pnp-cancel ctrl-btn ctrl-cancel">Cancel (Esc)</button> <button class="pnp-place ctrl-btn ctrl-place">Confirm (Enter)</button> </div>
5. picknplace.js accepts an options object during initialization. All selectors and class names can be customized:
root: The root element for event listeners. Default: document.listSelector: Selector for the container element. Default: .pnp-list.itemSelector: Selector for individual list items. Default: .pnp-item.controlsSelector: Selector for the global control container. Default: .pnp-controls.buttonsSelector: Selector for the button container within an item. Default: .pnp-buttons.pickSelector: Selector for the button that starts the pick action. Default: .pnp-pick.placeSelector: Selector for the button that confirms the new position. Default: .pnp-place.cancelSelector: Selector for the button that cancels the action. Default: .pnp-cancel.pickedClass: Class added to the item currently selected. Default: pnp-picked.realClass: Class applied to the original DOM elements. Default: pnp-real.ghostClass: Class applied to the floating duplicate element. Default: pnp-ghost.cloneClass: Class applied to the placeholder clones during sorting. Default: pnp-clone.createPickPlace({
// options here
}) Q: Can I use this library with dynamically added list items?
A: Yes. The library attaches event listeners to the root element using event delegation. New items added to the list automatically gain pick-and-place functionality.
Q: Does the library work with nested lists?
A: No. The current implementation assumes a flat list structure. Each createPickPlace instance targets a single list level. For nested hierarchies, you would need to create separate instances for each nesting level and handle the interaction boundaries manually.
Q: How do I persist the new order after placement?
A: The library reorders DOM elements but does not handle persistence. After a successful place event, read the new order from the DOM and send it to your backend. You can query all items with document.querySelectorAll('.pnp-item.pnp-real') and extract their data attributes or IDs in sequence.
Q: Can I customize the animation timing for item transitions?
A: Yes. The cloned items use CSS transforms for positioning. Add transition properties to the .pnp-clone class in your stylesheet. For example: .pnp-clone { transition: transform 0.3s ease-out; } will smooth the repositioning animations.
Q: Why does the ghost element sometimes appear offset during fast scrolling?
A: The library adjusts ghost position using CSS custom properties and requestAnimationFrame. On very fast scroll events, there may be a brief visual lag. This happens because the browser processes scroll events faster than animation frames. The offset corrects itself within one frame cycle.
The post Mobile-First Drag and Drop Alternative for List Reordering – picknplace.js appeared first on CSS Script.
As IGN Fan Fest 2026 comes to a close, and we celebrate our favorite franchises…
On Friday afternoon, Donald Trump posted on Truth Social, accusing Anthropic, the AI company behind…
For years, taking down a botnet meant finding its command-and-control (C2) server, seizing the domain,…
A Go-based command-and-control (C2) framework originally marketed within Chinese-speaking offensive security communities has been quietly…
A newly discovered malware campaign has been quietly targeting educational institutions and healthcare organizations across…
New filings announced last week aim to stop the Trump administration from further restricting federal…
This website uses cookies.