Skip to content
Knsept
Free playbook

Widget code style

How every widget in the library is written, so the code reads like an explanation, not a puzzle.

Updated Oct 23, 20262 min read

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, not btn; event, not e; progress, not p.
  • 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 attracts

Comment 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-visible style. 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" or aria-live region; decorative copies get aria-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.