Snap reticle
A reticle follows the pointer, spinning gently, and its corner brackets snap around buttons and links, matching their size and corners.
- enhancer
- cursor
- pointer
- focus
- buttons
- links
- 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.
Live demo
Snap reticle example
Code
It follows the controls above: change an option and the code changes with it.
<script src="https://search.axi0.io/axi0/motion/motion.js" defer></script>
<div class="m-ret-demo" data-motion="snap-reticle"><div class="m-ret-art" role="img" aria-label="An evening sky in orange and violet" data-reticle="View"></div><div class="m-ret-row"><button class="demo-btn" type="button">Play</button><button class="demo-btn" type="button" aria-label="Save">♡</button><button class="demo-btn" type="button">Share</button></div></div>
import { SnapReticle } from "./motion/react/SnapReticle";
<SnapReticle>Your content</SnapReticle>
<script setup lang="ts">
import SnapReticle from "./motion/vue/SnapReticle.vue";
</script>
<template>
<SnapReticle>Your content</SnapReticle>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "snap-reticle";
The wrappers: SnapReticle.tsx (React, TypeScript) and SnapReticle.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
Options
| Attribute | Default | What it does |
|---|---|---|
data-motion-targets | a, button, [data-reticle] | What the brackets snap to (a CSS selector) |
data-motion-color | auto | Bracket color (empty: the text color) |
data-motion-size | 12 | Half the reticle's size while it is free |
data-motion-spin | 1 | How fast the free reticle turns (0 stops it) |
data-motion-pad | 6 | Space between a target and the brackets |
data-motion-label | true | Show the target's name above it (its data-reticle, aria-label or text) |
data-motion-cursor | keep | Keep the system cursor or hide it inside the area |
Accessibility
The reticle is decoration (aria-hidden, no pointer events) and never takes the place of the real cursor by default. Keyboard focus moves the brackets onto the focused link or button, which makes a clear second focus marker; the page's own focus ring stays. Touch: a tap shows the brackets on what was tapped for a moment. Only transform, opacity and paint change, so nothing around it moves. Frames run through the shared loop, which stops off screen, in hidden tabs and under reduced motion; reduced motion shows the final state with no movement.
Size
snap-reticle.js is 2.2 KB gzip. A page loads the loader (2.9 KB) and core.js (1.4 KB) once, whatever it uses.