# Snapping

> What is moved comes to rest in line with what is around it, or on a grid, and shows the line it found.

When people move or resize something by hand, they are usually trying to put it
somewhere exact: in line with its neighbour, centred under a heading, on the
grid. Snapping finishes the gesture for them — and shows what it did.

## Best practices

**Snap to what is near and visible.** The edges and the middle of the thing
being moved are drawn to the edges and middles of the things around it. Where
nothing is near, and there is a grid, they are drawn to the grid.

**Take the nearest, and prefer an edge.** Of several lines within reach, the
nearest wins. Of two equally near, an edge wins over a middle: edges are what
people align by eye.

**Snap each direction by itself.** Something can come into line horizontally
with one neighbour and vertically with another.

**Measure the reach on the screen.** The distance within which a snap is taken
is a distance under the hand — a few pixels — whatever the zoom. Zoomed in,
people can place something a hair off a line; zoomed out, they cannot miss it.

**Show the line.** When something snaps, draw the line it snapped to, running
across everything that lies on it, for as long as it holds. A snap that cannot
be seen feels like the pointer sticking.

**Always offer a way out.** A modifier held during the drag — Control on most
platforms, Command on some — moves freely. Snapping that cannot be turned off
makes some positions unreachable.

**Leave the keyboard exact.** Arrow keys move by a fixed step, and by a larger
one with Shift. They do not snap.

**Stay immediate among thousands.** Gather the lines once, when the drag
begins, and search them in order: a drag among ten thousand things should cost
what one among ten does.

See also [Pan and zoom](https://ui.publictheta.com/foundations/viewport.md).

## Behaviour

Each statement is verified by a test in Chromium, Chromium (touch), Firefox, WebKit, WebKit (touch), unless it names the environments it applies to or is marked open.

### Lines

- Each thing offers its edges and its middle, along both axes, in order.
- The nearest line to a value is the nearest of all of them.
- Among no lines there is none.
- A value rests on a line when it is at one, and not when it is merely near.
- Finding the nearest among a million lines reads a few dozen of them.

### Moving

- An edge within the threshold of a line comes to rest on it, and the line is reported.
- An edge beyond the threshold stays where it is.
- The far edge and the middle snap as the near edge does.
- Of several lines within reach the nearest wins, and of two as near, an edge over a middle.
- The two axes snap independently.
- After a snap, the thing moved has a line of its own exactly on the line reported.
- With nothing near, a corner comes to rest on the grid; a line within reach is preferred to the grid.
- With nothing near and no grid, nothing changes.
- A single value — an edge being resized — snaps to a line, else to the grid, else stays.

### Guides

- A guide runs from the first to the last thing that has a line on it.
- A line nothing lies on has no guide.
- Along the other axis, a guide spans the things across.

## Reference implementation

React: `npx shadcn@latest add https://ui.publictheta.com/r/snap.json`
