A list whose items are rigid bodies stacked in a box: grab a card by a corner (it pivots around the grab point), toss it, the pile falls back under gravity and the DOM order follows the visual order. Home-grown physics engine (oriented boxes, friction, bounce), no dependencies.
Category
Micro-interactions
Type
Web Component (<mv-physics-stack>)
Status
beta
Keywords
physics, rigid-body, todo, list, reorder, drag, toss, gravity, tactile
When to use
A short to-do or idea list should feel tactile, with cards users can grab, toss and let fall into place
A playful demo or portfolio section should let visitors reorder items by throwing them around
Avoid when
Items must be reordered precisely across columns or statuses → use Kanban instead
Items are records with several fields to compare; a physics pile suits a handful of short cards, not dozens → use Table instead
Notifications should pile up physically in a corner tray → use Toast Physics instead
List items, in DOM order (= visual order once settled).
Methods
Name
Description
arrange()
Tidies the pile into a straight tower, in DOM order (smooth transition).
toss(item)
Spins the item out of the box, then removes it from the DOM; the cards above fall into the gap.
shake(strength = 1)
Gives every card a shake.
Events
Name
Description
mv-reorder
detail: { order, item } — the visual order changed (toss, Alt + arrows).
mv-settle
detail: { order } — the pile is at rest (the animation loop stops).
mv-toss
detail: { item } — an item was tossed out by toss().
Content structure
Name
Description
(children)
Each direct child becomes a card (mv-physics-stack-item class, role listitem). Adding or removing children is picked up: a new child drops in from the top.
CSS classes
Name
Description
mv-physics-stack-item
Set on each child; default card style, overridable.
CSS variables
Name
Default
Description
--mv-physics-stack-height
22rem
Box height.
--mv-physics-stack-item-width
min(19rem, 88%)
Card width.
--mv-physics-stack-bg
var(--mv-bg-subtle)
Box background.
Accessibility
role=list / listitem, each card is focusable. ↑/↓ move focus, Alt + ↑/↓ move the card (announced in a live region). The DOM is reordered to match the visual order and focus is preserved. Inner controls (buttons, links, fields) stay clickable and don’t start a grab. Reduced motion: the pile settles instantly, without animation. Without JS: a regular vertical list.