Weight Scrub

Interactive & Advanced · Animated · pure CSS

The cursor becomes a weight dial: sweep left-to-right to scrub Recursive's variable weight from feather-light to massive, while up-and-down leans the slant axis, all tracking the pointer live and smooth. Driven by @property-registered numbers fed a percentage-to-number calc off the pointer vars, with a short transition for buttery two-axis motion.

Weight Scrub

How it works

Weight Scrub is an animated interactive & advanced text effect rendered entirely in CSS. It animates a registered CSS @property, which keeps the motion smooth and GPU-friendly. It reacts to the pointer through CSS custom properties updated by a tiny inline script.

Controls

Weight Scrub exposes 5 dedicated controls — Hue, Feather, Massive, Slant and Smoothing — on top of the shared type controls (font, weight, letter-spacing and case). Open it in the generator to tune every value live, then copy the updated CSS.

CSS

/* Weight Scrub — made with TEXT-FX · https://text-fx.app
 * HTML: needs the small pointer-move JS snippet.
 * Font: 'Recursive', sans-serif (load from Google Fonts).
 */

@property --text-effect-w {
  syntax: "<number>";
  inherits: false;
  initial-value: 664;
}
@property --text-effect-sl {
  syntax: "<number>";
  inherits: false;
  initial-value: -2.5;
}

.text-effect {
  font-family: 'Recursive', sans-serif;
  font-weight: 700;
  letter-spacing: 8px;
  text-transform: none;
}

.text-effect {
  --mx: 50%;
  --my: 50%;
  --text-effect-w: calc(387 + (var(--mx) / 1%) * 5.54);
  --text-effect-sl: calc((var(--my) / 1%) * -0.05);
  color: hsl(34 55% 78%);
  font-variation-settings: 'wght' var(--text-effect-w), 'slnt' var(--text-effect-sl);
  transition: --text-effect-w 0.11s linear, --text-effect-sl 0.11s linear;
  cursor: ew-resize;
  will-change: font-variation-settings;
}

HTML

This effect needs the markup below (per-letter spans, SVG defs, or a data-text attribute).

<!-- Made with TEXT-FX · https://text-fx.app -->

<style>
@property --text-effect-w {
  syntax: "<number>";
  inherits: false;
  initial-value: 664;
}
@property --text-effect-sl {
  syntax: "<number>";
  inherits: false;
  initial-value: -2.5;
}

.text-effect {
  font-family: 'Recursive', sans-serif;
  font-weight: 700;
  letter-spacing: 8px;
  text-transform: none;
}

.text-effect {
  --mx: 50%;
  --my: 50%;
  --text-effect-w: calc(387 + (var(--mx) / 1%) * 5.54);
  --text-effect-sl: calc((var(--my) / 1%) * -0.05);
  color: hsl(34 55% 78%);
  font-variation-settings: 'wght' var(--text-effect-w), 'slnt' var(--text-effect-sl);
  transition: --text-effect-w 0.11s linear, --text-effect-sl 0.11s linear;
  cursor: ew-resize;
  will-change: font-variation-settings;
}
</style>

<div class="text-effect">Your text</div>

<script>
const fx = document.querySelector('.text-effect');
if (fx) {
  fx.addEventListener('pointermove', (e) => {
    const r = fx.getBoundingClientRect();
    if (!r.width || !r.height) return;
    fx.style.setProperty('--mx', ((e.clientX - r.left) / r.width) * 100 + '%');
    fx.style.setProperty('--my', ((e.clientY - r.top) / r.height) * 100 + '%');
  });
  fx.addEventListener('pointerleave', () => {
    fx.style.removeProperty('--mx');
    fx.style.removeProperty('--my');
  });
}
</script>
Category
Interactive & Advanced
Type
Animated
Browser support
Cursor scrubs Recursive's wght/slnt axes live via pointer-tracked typed math (@property + var()/1%); engines without it rest at a mid weight. Static preview shows the centred resting frame.
Capabilities
pure, property, pointer

Related Interactive & Advanced effects