Close Button Animation
An X close button whose strokes turn a quarter turn on hover, squeeze on press, and send the card away toward its corner.
Invite sent to Sam
sam@acme.co can now edit the acme workspace.
Build an animated close button (an X icon) and the card or modal it closes. Structure: a card or dialog with a title and a line of text. In its top-right corner, a round icon button about 30px wide containing an X made of two SVG strokes (M6 6 L18 18 and M18 6 L6 18 in a 24px viewBox, round line caps). Give the title right padding so it never runs under the button. Hover and focus: - The X rotates exactly 90 degrees on a spring (stiffness ~420, damping ~22). Ninety degrees lands on the same shape, so it feels like a nod, not a spinner. - Behind the strokes, a circle in the text color at ~9% opacity scales from 0.4 to 1 over 220ms and fades in. The hit area appears when you are about to use it. - The icon color goes from muted to full text color in 180ms. Press: on pointer down the X scales to 0.8 and the disc to 0.86, both springing back on release. Closing: the card exits in 220ms with opacity to 0 and scale to 0.86, transform-origin top right, easing that accelerates (cubic-bezier(0.4, 0, 1, 1)). It visibly leaves toward the button that closed it. Opening does the reverse: from scale 0.92, 8px lower, on a spring. When the card opens, draw the X in with pathLength from 0 to 1, the second stroke starting 120ms after the first, 260ms each. Behaviour: Escape closes the dialog. After closing, return focus to the element that opened it. Accessibility: a real button element with aria-label "Close"; the card has role="dialog" and aria-labelledby pointing at its title; the SVG is aria-hidden. Under prefers-reduced-motion, skip the rotation, the draw and the scale: the card simply disappears and the hover disc stays as a plain state change. Colors as tokens: surface for the card, hairline for its border, muted for the resting X, text for the hovered X and (at low opacity) for the disc. No accent is needed; a close button should never compete with the primary action. Build the component, not this demo of it. - Ambient motion that IS the component may loop: a drifting background, a marquee, a spinner while something is genuinely loading. - Do not add any timer, interval, loop or script that performs a person's action by itself. No auto-hover, no auto-click, no cycling through states, no pretend submitting, no replaying the interaction on a schedule. - Every state that answers a person waits for a real event from that person. - Placeholder copy and sample content are welcome. Simulated behaviour is not.