Library widgets are meant to be read before they're pasted. If you have to decode the code to trust it, it isn't done yet. These are the rules every widget follows.
Say what it does first
Every script opens with a one- or two-sentence comment in plain language: what the widget does and how, before any code.
// Hold-to-confirm: the action only runs if you keep holding for `holdDuration`.
// Releasing early cancels and the bar drains back to empty.Names that read like sentences
- camelCase for variables and functions:
holdDuration,moveIndicatorTo,prefersReducedMotion. - Whole words, not abbreviations:
button, notbtn;event, note;progress, notp. - Functions are verbs (
showToast,cancelHold), booleans are questions (isDone,isOutsideZone). - Class names say what the thing is, in kebab-case:
.toast-trigger,.hold-fill,.tab-indicator.
Settings live at the top
Anything you might want to tweak is a named constant at the top of the script, with its unit in a comment:
const holdDuration = 1000; // ms you have to hold
const attractionZone = 90; // px around the button that attractsComment the why, not the what
Code already says what happens. Comments explain why, especially anything that looks odd:
touch-action: none; /* a touch drag moves the button instead of scrolling the page */If a line needs a comment to explain what it does, rename things first.
Every input, every setting
- Mouse, touch, pen: use pointer events. Anything that relies on hover gets a touch alternative (press and drag, tap).
- Keyboard: everything clickable is a real
<button>or link, with a visible:focus-visiblestyle. Custom controls follow the matching WAI-ARIA pattern. - Reduced motion: tone motion down instead of removing the feature. Show the end state, fade instead of slide, or slow it down.
- Screen readers: status changes go in a
role="status"oraria-liveregion; decorative copies getaria-hidden="true".
Small and dependency-free
Plain HTML, CSS and JavaScript, no libraries and no build step. CSS does the animation; JavaScript sets classes, attributes or custom properties and lets CSS take it from there. If the script fails, the content should still be visible and usable.
See them in practice in the library.