Text Fill
`<pura-text-fill>` is the motion.dev "Fill text" move: the slotted text starts as a faint base color and fills with the real color as you scroll. The trick is two stacked copies of the text: a faint base layer and a full-color top layer clipped by an animating `inset()` that slides open along the fill axis (clip-path interpolates natively; `background-clip: text` is avoided because it cannot paint slotted glyphs and breaks `currentColor`). By default (`trigger="scrub"`) the fill is tied 1:1 to a scroll-driven timeline (`animation-timeline: view()`), so there is no per-frame JS; `trigger="view"` fills once on scroll-in with a spring ease, `trigger="load"` on connect. `direction` picks the sweep (`right`, `left`, `down`, `up`). Colors come from `--pura-text-fill-color` (default `currentColor`) and `--pura-text-fill-base` (default 18% `currentColor`). SSR and no-JS render the text in its normal color; reduced motion lands filled. Each instance registers in `window.__puraTextFills` by `data-pura-id` with `{ direction, replay }`.
Preview
<!-- fill tied 1:1 to scroll (default) -->
<pura-text-fill>
Reads like a highlight following your scroll.
</pura-text-fill>
<!-- fill once when it enters the viewport -->
<pura-text-fill trigger="view" direction="down" preset="slow">
Fills top to bottom on arrival.
</pura-text-fill>
<!-- custom colors -->
<pura-text-fill style="--pura-text-fill-color: #a3e635; --pura-text-fill-base: #3f3f46;">
Lime over zinc.
</pura-text-fill> Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
direction | "right" | "left" | "down" | "up" | right | Which way the fill sweeps across the text. |
trigger | "scrub" | "view" | "load" | scrub | scrub ties the fill 1:1 to a scroll-driven timeline; view fills once when scrolled into view; load fills once on connect. |
timeline | "view" | "scroll" | view | Scrub only: view maps the element's own view progress; scroll maps the nearest scroll container. |
range | string | cover 0% cover 60% | animation-range for the scrub (e.g., "cover 0% cover 50%"). |
preset | "default" | "gentle" | "wobbly" | "stiff" | "slow" | "snappy" | default | Spring profile for view/load easing. Or set stiffness/damping/mass directly. |
Installation
pura is copy-paste and dependency-free. Load the whole library, or just this component.
<link rel="stylesheet" href="/pura/tokens.css">
<script type="module" src="/pura/lib/text-fill.js"></script> import "./pura/lib/text-fill.js";