Skip to content

icon

aa-hover="icon-<direction>" swaps an icon for a duplicate that slides in from the opposite side. The library finds the first descendant <svg>, wraps it in a clip box, clones it, and animates both with one timeline. No markup changes required.

Hover effects are skipped on touch-only devices via (hover: hover) so iOS / Android don't fire stuck animations on tap.

<direction> is one of: up, down, left, right, up-right, up-left, down-right, down-left. The original slides off in that direction; the clone enters from the opposite side and lands where the original was.

VariantEffect
icon-rightOriginal slides right, clone enters from the left
icon-up-rightDiagonal slide — original up-right, clone from down-left
icon-down-leftDiagonal slide — original down-left, clone from up-right
…and the other fiveSame pattern, mirrored

Both flags are space-separated and combinable.

FlagWhat it does
reverseMouseleave reverses the timeline instead of restarting on every enter. Better fit for toggling buttons / CTAs
tripleAdds a second clone two "from" steps offscreen and doubles the slide distance — the first clone passes through centre at the midpoint, the second clone lands at centre
<a aa-hover="icon-up-right"></a> <!-- restart on enter -->
<a aa-hover="icon-up-right reverse"></a> <!-- reverse on leave -->
<a aa-hover="icon-up-right triple"></a> <!-- chain of three -->
<a aa-hover="icon-up-right triple reverse"></a> <!-- both -->
AttributeDefaultNotes
aa-hover(required)icon-<direction> plus optional reverse / triple flags
aa-colorcurrentColorColour applied to the cloned SVG(s) only — the original keeps the inherited colour. Use to make the slide-in clone stand out against a coloured hover background (e.g. aa-color="#ffffff" on an icon inside a curve button filling black). Requires the SVG to use stroke="currentColor" or fill="currentColor".
aa-duration(init)seconds — falls back to init({ duration }) (default 0.6)
aa-delay0seconds before the enter animation starts
aa-ease(init)any GSAP ease — falls back to init({ ease }) (default power4.out)
aa-intensity1multiplier on the base 50 ms lag between each successive icon starting its slide — 2 doubles the gap (slower trail), 0.5 halves it (tighter chain)

The first descendant <svg> is wrapped in a <span aa-hover-icon-clip> (inline-flex; position: relative; overflow: hidden); a cloned SVG is appended next to it, absolutely positioned at the appropriate offset for the chosen direction. With the triple flag, two clones are appended (one at the standard "from" offset, the second one at double that distance). The wrapper and clones unwrap cleanly on dispose.

Because the wrapper sets inline-flex, the icon stays aligned with adjacent text. If your icon is display: block and you need the wrapper to behave the same way, override [aa-hover-icon-clip] in your own CSS.

gsap.

Same directions, but with triple so a chain of three icons slides through. The middle clone is briefly visible at centre on the way through; the second clone is the one that lands.