Sortable list

정렬 가능한 목록

A vertical list whose items can be reordered by dragging a grip handle.

Also known as: Reorderable listDraggable list
···
html
<ul class="slw" id="slw">
  <li draggable="true"><i class="slgrip">⋮⋮</i>결제 수단 확인</li>
  <li draggable="true"><i class="slgrip">⋮⋮</i>배송지 입력</li>
  <li draggable="true"><i class="slgrip">⋮⋮</i>주문 검토</li>
  <li draggable="true"><i class="slgrip">⋮⋮</i>최종 결제</li>
</ul>
css
.slw{list-style:none;margin:0;padding:0;width:min(220px,90%);display:grid;gap:6px}
.slw li{display:flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:8px 10px;font-size:11px;color:var(--fg);cursor:grab;transition:transform .25s,opacity .25s}
.slw li[data-drag]{opacity:.4}
.slgrip{font-style:normal;letter-spacing:-2px;color:var(--muted);font-size:11px}
js
const list = document.getElementById('slw');
let dragEl = null;
list.querySelectorAll('li').forEach((li) => {
  li.addEventListener('dragstart', () => { auto = false; dragEl = li; li.setAttribute('data-drag', ''); });
  li.addEventListener('dragend', () => li.removeAttribute('data-drag'));
  li.addEventListener('dragover', (e) => {
    e.preventDefault();
    if (!dragEl || dragEl === li) return;
    const rect = li.getBoundingClientRect();
    const before = e.clientY < rect.top + rect.height / 2;
    list.insertBefore(dragEl, before ? li : li.nextSibling);
  });
});
let auto = true;
function swap() {
  if (!auto) return;
  const items = [...list.children];
  const i = Math.floor(Math.random() * (items.length - 1));
  items[i].after(items[i + 1]);
  setTimeout(swap, 1300);
}
setTimeout(swap, 900);

This entry covers the list UI that results from reordering — the frame-by-frame math of tracking a pointer and computing which slot it's hovering over lives in the interaction category's "Drag to Reorder" entry. The two describe the same pattern from different angles: what it shows versus how it's computed.

The difference from a kanban board, covered there, is what changes — a sortable list only changes rank within one list; items never leave their category. Order itself often carries meaning (priority, a playlist's sequence, checklist progress), so an <ol> is frequently the more accurate markup than a plain <ul>.

Dragging is mouse-only, so keyboard users need an alternative — "Move up"/"Move down" buttons on each item, or selecting an item and reordering it with arrow keys.