motion-strike

A line that draws itself through a phrase, from left to right, when it scrolls into view. Use it for an old price, a removed step or a word you replace.

Preview

€49 €29 per month

Import

import 'motion-components/motion-strike'   // just this one
import 'motion-components'               // or the whole library

Usage

Wrap the component in <del> when the strike means removed, so screen readers know.

<del><motion-strike>€49</motion-strike></del> <ins>€29</ins> per month

Then mark the replacement

Draw the strike first, then another mark with delay.

From a manual checklist to fully automated.

From a <motion-strike>manual checklist</motion-strike>
to <motion-marker delay="0.6">fully automated</motion-marker>.

Loop

Add loop to draw, hold, undraw and draw again. hold sets how long the line stays through the text, gap how long it stays away. The line erases from its start, so it leaves at its end.

Was €49, now €29.

<del><motion-strike loop hold="1.2">€49</motion-strike></del> <ins>€29</ins>

Properties

Attribute Property Type Default Description
trigger trigger string 'view' What draws the mark: 'view' when it scrolls into view, 'hover' on pointer enter (it undraws on leave), or 'mount' when it connects
duration duration number 0.6 Spring duration of the drawing, in seconds
delay delay number 0 Seconds to wait before drawing. Use it to draw several marks in one sentence one after another
bounce bounce number 0 Spring bounciness. 0 keeps the stroke from overshooting the text
loop loop boolean false Draw, hold, undraw and draw again on repeat. With trigger="view" the cycle runs while the mark is on screen
hold hold number 1.6 With loop, seconds the mark stays drawn before it undraws
gap gap number 0.5 With loop, seconds the mark stays undrawn before it draws again
pause-on-hover pauseOnHover boolean false Pause the loop while the pointer is over the mark, resuming on leave
once once boolean true With trigger="view", draw only the first time. Set once="false" to undraw when it leaves and draw again on every entry. Ignored with loop
threshold threshold number 0.6 Share of the element, from 0 to 1, that must be visible before it draws

CSS custom properties

Property Type Default Description
--mc-mark-color color currentColor Color of the line
--mc-mark-thickness length 2px Thickness of the line

JavaScript API

The mark has the shared playback API: play() draws it, cancel() removes it, finish() shows it fully drawn and replay() draws it again from the start. It fires motion-start, motion-finish and motion-cancel. With trigger="hover", each draw and undraw is a playback run too, so it fires motion-start and motion-finish. See the JavaScript API.

sweep() runs a fully drawn mark across once: it erases from its start, so it leaves at its end, then draws in again. It is a playback run, so it fires motion-start and motion-finish, and pause(), finish() and cancel() act on it. It does nothing under reduced motion or while the mark is not fully drawn.

Accessibility

The mark is decoration: the text stays real, selectable and read by screen readers exactly as written. The line alone does not tell screen readers the text is removed; wrap it in <del> when it is. Respects prefers-reduced-motion: the mark appears fully drawn at once, with no animation, and loop never starts.