2026-10-26·by Sijie Wang#design#ergonomics#fitts-law

fitts-law

Fitts' law: aimed-movement time depends on the ratio of distance to width

What it is for. Predicting how long an aimed movement takes (mouse to a button, finger to a target) so hit targets can be sized and placed on evidence instead of taste.

The formula.

MT=a+b×log⁡2(D/W+1)MT = a + b \times \log_2(D/W + 1)

MT is movement time, D is distance to the target, W is the target's width measured ALONG the direction of movement. ID = log2(D/W + 1) is the index of difficulty, in bits. The constants a and b are fitted from experiment (Fitts 1954 tapping experiments), not derived from first principles, and b differs by device: mouse, trackpad, and stylus do not share one b.

Why the ratio, not distance alone. Time grows with the logarithm of D/W: doubling the distance does not double the time, and doubling the width gives diminishing returns. What matters is the ratio, and W is directional: a wide but short button approached from the side is still hard, because its width along the movement axis is small.

D = 400px, W = 36px, ID about 3.60 bits:

∙  \bullet\ \raisebox{0.35em}{\rule{10em}{0.12em}}\ \rule{0.9em}{0.9em}

D = 400px, W = 44px, ID about 3.33 bits:

∙  \bullet\ \raisebox{0.45em}{\rule{10em}{0.12em}}\ \rule{1.1em}{1.1em}

The distance is identical in both rows. The target is only 8px wider in reality, and the ID drops 0.27 bits: that is the ratio at work.

Edge and corner: width made infinite. A pointer cannot travel past the screen edge; it stops there. A button flush against the edge therefore has effectively infinite width in the edge direction: overshoot still lands on it, and no aiming precision is needed on that axis. With W approaching infinity, ID approaches log2(1) = 0, and only the baseline a remains. A corner is infinite on two axes at once, which is why corners are the easiest targets on a desktop.

Scope: pointer only. The edge trick holds for pointer devices. It fails on multi-monitor inner edges (the pointer passes through to the next screen, so the edge is not a stop) and it fails on touch: there is no cursor to stop, the finger occludes the target, and edge targets are harder to reach, not easier. Touch replaces the edge trick with a minimum size: 44pt (Apple HIG) / 48dp (Material), derived from finger-pad size.

Worked measurement: Lucerna reader header (code-measured, 2026-10-25).

  • Design-system Button sizes (repo main snapshot, July 2026): default 36px tall, sm 32px, lg 40px, icon 36x36px, glyph 16px, radius 4px. Note: MainApp consumes a newer published design-system than this snapshot, so shipped sizes may have moved.
  • The reader header carries about 14 actions (back, bookmark, contents, bookmarks, vocabulary, notes, search, go-to-page, AI settings, theme, font size, prev/next page, menu, user menu, counted from the wrapper's props). That count is the Hick side of the bargain: Fitts wants targets big, Hick wants options few, and the header is where the two negotiate.
  • Breakpoints: Tailwind v4's sm defaults to 640px and MainApp does not customize it, but the reader uses no sm:/md:/lg: classes at all. The real split is a JS hook, useCompactViewport, with a max-width: 639px boundary: below 640px is the compact layout (with its own mobile page nav and one-step-smaller body type), at and above 640px the full layout. The 640 and 639 figures are two sides of the same line, implemented in code rather than in responsive classes.
  • Effect size (stated assumptions: mouse, b about 100ms/bit, relative comparison only): at D = 400px, W = 36px gives ID about 3.60 bits and W = 44pt gives about 3.33 bits, a saving of about 0.27 bits or roughly 27ms per hit. At D = 800px the saving is about 0.28 bits. The saving is nearly distance-independent, a property of the log ratio.
  • NOT verified: whether the reader header sits flush against the viewport top edge, which would decide whether it earns the edge benefit. That layout lives in the published core UI package (0.5.75), which is not in the core repo's main branch, so no edge claim is made for it here.

How to dig deeper on an ergonomics question (the five questions).

  1. Origin: which experiment produced this number or constant?
  2. Boundary: under what conditions does the rule fail?
  3. Counterparty: which other rule does it trade against?
  4. Measurement: what do the real interface's numbers say, measured from code?
  5. Counterexample: where does following the rule make things worse?

Agent audit checklist: read this node, then check an interface against every line, and report each item with evidence (a file, a config, or a computed ID).

  1. Target sizes per device, measured from code: heights, widths, and icon sizes, per breakpoint. Compare against 44pt/48dp on touch.
  2. Edge and corner placement: which targets sit on a true screen edge, and is the device a pointer device? Inner multi-monitor edges do not count.
  3. IDs for the top tasks: state D and directional W for each, compute ID, and compare alternatives by bits, not by feel.
  4. Hick tension: count the actions sharing the surface, and state what shrinking or grouping would cost.
  5. Touch behavior: where the same surface is touched rather than pointed at, does the edge reasoning still appear? If yes, flag it.
  6. Unverified claims: list what could not be confirmed from code, and do not present it as measured.
about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →