Copy to Clipboard Button
A snippet block whose copy button morphs its clipboard icon into a stroke-drawn check, floats a Copied pill up beside it and flashes the code it took.
About This Component
Copy buttons usually swap a word and hope you noticed. This one answers in three places at once: the clipboard icon shrinks and tips away while a tick scales in and draws itself stroke-first, a small pill rises above the button and fades in, and the snippet itself flashes so it is obvious which block was taken.
Read the full effect overview
The failure path is designed rather than ignored. When the Clipboard API is missing or refuses, the button shakes, turns to its error colour, selects the whole snippet for you and says so in a live region, so the keyboard shortcut is one press away. One HTML file, one stylesheet, one script, GSAP core only, and three shipped looks switched by a data-variant attribute.
What's Included
- Clipboard icon tips and shrinks away while a tick scales in over it
- The tick draws itself by tweening strokeDashoffset, no DrawSVG plugin needed
- Copied pill rises and fades in above the button, then leaves upward
- The snippet flashes its accent so it is clear which block was copied
- Clipboard failure shakes the button, selects the code and explains itself
- A demo toggle simulates the no-clipboard case so the fallback is visible
- Every state change announced through an aria-live status line
- Reduced motion switches states instantly instead of animating
- window.copyButton.copy / reset / text for your own code
- Three shipped variants: vault, glass, paper
Perfect For
- Documentation and API reference code blocks
- Install commands and CLI snippets on product pages
- Copyable tokens, keys and share links in dashboards
- Any copy control that currently just swaps its label to Copied
How It Works
Two icons, one slot
The clipboard and the tick are two SVGs absolutely stacked in a 17 pixel box. Copying tweens the clipboard's opacity, scale and rotation away and scales the tick in behind it on a back ease, so the swap reads as one object changing rather than two elements toggling. Nothing in the CSS sets a transform on either, so every scale and rotation starts from a real zero.
Drawing the tick
The tick is one SVG path. Its length is read once with getTotalLength, then strokeDasharray and strokeDashoffset are both set to that length so the stroke is fully retracted. GSAP tweens strokeDashoffset to zero and the line draws itself. That is the whole trick, and it needs no plugin.
The failure path is a state, not an error
The copy runs through the Clipboard API's promise, and both a missing API and a rejected write land in the same handler. That handler puts the button into its error colour, shakes it on x, selects the snippet with a Range so the keyboard shortcut works, and writes a sentence explaining what happened into the live region. A demo toggle forces that path so the state can be seen without breaking the browser.
Colours come from the variant
The snippet flash and both pill colours are read from the --code-flash, --code-bg, --pill-ok-bg and --pill-err-bg custom properties with getComputedStyle at the moment each tween starts, never hard-coded in the script. The flash hands the background back to the stylesheet with clearProps when it lands, so switching data-variant afterwards is never stuck on the previous look.