Esc

Try “tilt”, “reveal”, “drag”, or “reduced motion”.

Guide

Drag

Draggable elements, bounds, and what happens on release.

--k-drag makes an element draggable with mouse, touch, or pen.

.sticker {
  --k-drag: both;
}

x or y limits dragging to one axis, for sliders and sheets. Kinesis sets touch-action, so a drag on a phone doesn't scroll the page, and a horizontal drag still lets the page scroll vertically.

Pull me
Throw me
Drag the cardsEdit
.drag-zone {
  position: relative;
  height: 100%;
}

.drag-card {
  --k-drag: both;
  position: absolute;
  top: calc(50% - 60px);
  display: grid;
  place-items: center;
  width: 120px;
  height: 120px;
  border-radius: 22px;
  color: #fff;
  font-weight: 600;
  cursor: grab;
  user-select: none;
}

.drag-card[data-kinesis-dragging] {
  cursor: grabbing;
}

.drag-card--return {
  --k-release: return;
  --k-motion: bouncy;
  left: calc(30% - 60px);
  background: #ff5d6c;
}

.drag-card--throw {
  --k-release: throw;
  --k-bounds: parent;
  left: calc(70% - 60px);
  background: #2f6bff;
}

Release

--k-release sets what happens when you let go:

ValueBehavior
throw (default)glides on with the release speed and comes to a stop
staystops where you let go
returnsprings back home with the element's --k-motion
.pull-tab {
  --k-drag: y;
  --k-release: return;
  --k-motion: bouncy;
}

Bounds

--k-bounds keeps the element inside its parent, the scope, or the viewport. Dragging past the edge stretches elastically, and the element settles back inside on release.

.puck {
  --k-drag: both;
  --k-bounds: parent;
}

Styling while dragging

A dragged element has a data-kinesis-dragging attribute:

.sticker { cursor: grab; }
.sticker[data-kinesis-dragging] { cursor: grabbing; }

A drag doesn't count as a click, so draggable links and buttons don't fire when dropped.

Reacting in JavaScript

dragstart, drag, and dragend receive the offset from the resting position and the pointer velocity:

import { kinesis } from "@amineyarman/kinesis"

kinesis(document.querySelector(".sheet")).on("dragend", ({ y, velocityY }) => {
  if (y > 200 || velocityY > 800) closeSheet()
})

The element also receives them as kinesis:dragstart, kinesis:drag, and kinesis:dragend DOM events.

Keyboard

Arrow keys move a focused draggable element by 10px, or 50px with Shift, within its bounds. Kinesis doesn't make elements focusable. If dragging matters in your interface, add tabindex="0" and a label.

Combining with other effects

A draggable element can also tilt, pull magnetically, or react to hover. The drag offset adds on top.

Edit this page on GitHub