Arrow swap button
On hover the arrow exits the button on one side while a fresh arrow enters from the other.
CSSBeginner
<a class="btn" href="#">Start a project
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
</span>
</a>
.btn{display:inline-flex;align-items:center;gap:14px;padding:10px 12px 10px 24px;border-radius:999px;background:#f08a5d;color:#270100;font-weight:700;text-decoration:none;
transition:transform .2s,background .3s}
.btn:active{transform:scale(.96)}
.icon{position:relative;width:38px;height:38px;border-radius:50%;background:#270100;color:#f08a5d;overflow:hidden;display:grid;place-items:center}
.icon svg{position:absolute;width:18px;height:18px;transition:transform .45s cubic-bezier(.2,.8,.2,1)}
.icon svg+svg{transform:translateX(-200%)}
.btn:hover .icon svg:first-child,.btn:focus-visible .icon svg:first-child{transform:translateX(200%)}
.btn:hover .icon svg+svg,.btn:focus-visible .icon svg+svg{transform:none}
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Arrow swap</title>
<style>
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{display:grid;place-items:center;background:#140807;color:#fffffc;font:16px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif}
.btn{display:inline-flex;align-items:center;gap:14px;padding:10px 12px 10px 24px;border-radius:999px;background:#f08a5d;color:#270100;font-weight:700;text-decoration:none;
transition:transform .2s,background .3s}
.btn:active{transform:scale(.96)}
.icon{position:relative;width:38px;height:38px;border-radius:50%;background:#270100;color:#f08a5d;overflow:hidden;display:grid;place-items:center}
.icon svg{position:absolute;width:18px;height:18px;transition:transform .45s cubic-bezier(.2,.8,.2,1)}
.icon svg+svg{transform:translateX(-200%)}
.btn:hover .icon svg:first-child,.btn:focus-visible .icon svg:first-child{transform:translateX(200%)}
.btn:hover .icon svg+svg,.btn:focus-visible .icon svg+svg{transform:none}
</style></head>
<body>
<a class="btn" href="#">Start a project
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
</span>
</a>
</body></html>
Good for
Calls to action and read-more links.
Watch out for
Clip the icon box with overflow hidden so the exiting arrow never leaks outside the button.
Accessibility
Wrap motion in @media (prefers-reduced-motion: reduce) and switch it off or shorten it for people who ask for less movement.