Crosshair
Hairlines follow the pointer with its position and lock onto links and buttons to measure them.
- enhancer
- cursor
- pointer
- measure
- since 0.2
Background Studio: tune it below, then copy the code
Your system asks for reduced motion: the demo shows its final state and nothing moves.
Code
It follows the controls above: change an option and the code changes with it.
<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>
<div class="m-crosshair" data-motion="crosshair">
<p>Move the pointer around. Over a link or a button the lines lock on and measure it.</p>
<div><a href="#crosshair">A link</a> <button type="button">A button</button> <button type="button" class="m-crosshair-big">A bigger one</button></div>
</div>
import { Crosshair } from "./motion/react/Crosshair";
<Crosshair>Your content</Crosshair>
<script setup lang="ts">
import Crosshair from "./motion/vue/Crosshair.vue";
</script>
<template>
<Crosshair>Your content</Crosshair>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "crosshair";
The wrappers: Crosshair.tsx (React, TypeScript) and Crosshair.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
Options
| Attribute | Default | What it does |
|---|---|---|
data-motion-pad | 6 | the frame's distance from a locked element, in pixels |
Accessibility
The real pointer is never hidden: the lines only add to it. Everything moves with transforms in one clipped layer, so nothing shifts. Keyboard focus on a link or a button inside locks the frame onto it; a tap places the lines for a moment. Reduced motion: the lines jump without easing. The layer is decorative and hidden from screen readers.
Size
crosshair.js is 2.0 KB gzip. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.