Open demo

CSS code

HTML
<button type="button" class="ab ab-next">Continue <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></button>
<button type="button" class="ab ab-down">Download <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4v11M7 11l5 5 5-5M5 20h14"/></svg></button>
<button type="button" class="ab ab-out">Open docs <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14 5h5v5M19 5l-8 8M18 14v5H5V6h5"/></svg></button>
<button type="button" class="ab ab-spin">Refresh <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 12a8 8 0 11-2.3-5.7"/><path d="M20 4v5h-5"/></svg></button>
<button type="button" class="ab ab-circle" aria-label="Next"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
CSS
/* Buttons with moving icons: the SVG (aria-hidden) nudges in the direction of the action on hover and on keyboard focus. */
.ab{display:inline-flex;align-items:center;gap:10px;border:0;border-radius:11px;padding:13px 24px;font:inherit;font-size:.92rem;font-weight:700;
  line-height:1.25;cursor:pointer;transition:background-color .18s,border-color .18s,color .18s}
.ab svg{width:17px;height:17px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;transition:transform .22s cubic-bezier(.4,0,.2,1)}
.ab:focus-visible{outline:2px solid #4f46e5;outline-offset:3px}
.ab-next{background:#4f46e5;color:#fff}
.ab-next:hover{background:#4338ca}
.ab-next:hover svg,.ab-next:focus-visible svg{transform:translateX(5px)}
.ab-down{background:#101828;color:#fff}
.ab-down:hover{background:#344054}
.ab-down:hover svg,.ab-down:focus-visible svg{transform:translateY(3px)}
.ab-out{background:#fff;color:#344054;border:1.5px solid #858c98}
.ab-out:hover{border-color:#344054}
.ab-out:hover svg,.ab-out:focus-visible svg{transform:translate(2px,-2px)}
.ab-spin{background:#e0f2fe;color:#0369a1}
.ab-spin svg{transition-duration:.3s}
.ab-spin:hover svg,.ab-spin:focus-visible svg{transform:rotate(180deg)}
.ab-circle{justify-content:center;width:44px;height:44px;padding:0;border:1.5px solid #858c98;border-radius:999px;background:transparent;color:#344054}
.ab-circle:hover{background:#101828;border-color:#101828;color:#fff}
.ab-circle:hover svg,.ab-circle:focus-visible svg{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){.ab,.ab svg{transition:none}.ab:hover svg,.ab:focus-visible svg{transform:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<button type="button" class="btn btn-arrow btn-arrow-next d-inline-flex align-items-center">Continue <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></button>
<button type="button" class="btn btn-arrow btn-arrow-down d-inline-flex align-items-center">Download <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4v11M7 11l5 5 5-5M5 20h14"/></svg></button>
<button type="button" class="btn btn-arrow btn-arrow-out d-inline-flex align-items-center">Open docs <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14 5h5v5M19 5l-8 8M18 14v5H5V6h5"/></svg></button>
<button type="button" class="btn btn-arrow btn-arrow-spin d-inline-flex align-items-center">Refresh <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 12a8 8 0 11-2.3-5.7"/><path d="M20 4v5h-5"/></svg></button>
<button type="button" class="btn btn-arrow btn-arrow-circle rounded-circle d-inline-flex align-items-center justify-content-center" aria-label="Next"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
CSS
/* .btn with d-inline-flex utilities; colours per variant through --bs-btn-* variables, the SVG moves on hover and focus. */
.btn-arrow{--bs-btn-padding-x:24px;--bs-btn-padding-y:13px;--bs-btn-font-size:.92rem;--bs-btn-font-weight:700;--bs-btn-line-height:1.25;
  --bs-btn-border-width:0;--bs-btn-border-radius:11px;--bs-btn-focus-box-shadow:none;gap:10px;transition:background-color .18s,border-color .18s,color .18s}
.btn-arrow svg{width:17px;height:17px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;transition:transform .22s cubic-bezier(.4,0,.2,1)}
.btn-arrow:focus-visible{outline:2px solid #4f46e5;outline-offset:3px}
.btn-arrow-next{--bs-btn-color:#fff;--bs-btn-bg:#4f46e5;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4338ca;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4338ca}
.btn-arrow-next:hover svg,.btn-arrow-next:focus-visible svg{transform:translateX(5px)}
.btn-arrow-down{--bs-btn-color:#fff;--bs-btn-bg:#101828;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#344054;--bs-btn-active-color:#fff;--bs-btn-active-bg:#344054}
.btn-arrow-down:hover svg,.btn-arrow-down:focus-visible svg{transform:translateY(3px)}
.btn-arrow-out{--bs-btn-border-width:1.5px;--bs-btn-color:#344054;--bs-btn-bg:#fff;--bs-btn-border-color:#858c98;
  --bs-btn-hover-color:#344054;--bs-btn-hover-bg:#fff;--bs-btn-hover-border-color:#344054;
  --bs-btn-active-color:#344054;--bs-btn-active-bg:#fff;--bs-btn-active-border-color:#344054}
.btn-arrow-out:hover svg,.btn-arrow-out:focus-visible svg{transform:translate(2px,-2px)}
.btn-arrow-spin{--bs-btn-color:#0369a1;--bs-btn-bg:#e0f2fe;--bs-btn-hover-color:#0369a1;--bs-btn-hover-bg:#e0f2fe;--bs-btn-active-color:#0369a1;--bs-btn-active-bg:#e0f2fe}
.btn-arrow-spin svg{transition-duration:.3s}
.btn-arrow-spin:hover svg,.btn-arrow-spin:focus-visible svg{transform:rotate(180deg)}
.btn-arrow-circle{--bs-btn-padding-x:0;--bs-btn-padding-y:0;--bs-btn-border-width:1.5px;
  --bs-btn-color:#344054;--bs-btn-bg:transparent;--bs-btn-border-color:#858c98;
  --bs-btn-hover-color:#fff;--bs-btn-hover-bg:#101828;--bs-btn-hover-border-color:#101828;
  --bs-btn-active-color:#fff;--bs-btn-active-bg:#101828;--bs-btn-active-border-color:#101828;width:44px;height:44px}
.btn-arrow-circle:hover svg,.btn-arrow-circle:focus-visible svg{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){.btn-arrow,.btn-arrow svg{transition:none}.btn-arrow:hover svg,.btn-arrow:focus-visible svg{transform:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<button type="button" class="group inline-flex cursor-pointer items-center gap-2.5 text-[.92rem] leading-[1.25] font-bold transition-[background-color,border-color,color] duration-[180ms] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#4f46e5] motion-reduce:transition-none rounded-[11px] px-6 py-[13px] bg-[#4f46e5] text-white hover:bg-[#4338ca]">Continue <svg viewBox="0 0 24 24" aria-hidden="true" class="size-[17px] shrink-0 fill-none stroke-current stroke-[2.2] transition-transform duration-[220ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none group-hover:translate-x-[5px] group-focus-visible:translate-x-[5px] motion-reduce:translate-x-0!"><path d="M5 12h14M13 6l6 6-6 6"/></svg></button>
<button type="button" class="group inline-flex cursor-pointer items-center gap-2.5 text-[.92rem] leading-[1.25] font-bold transition-[background-color,border-color,color] duration-[180ms] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#4f46e5] motion-reduce:transition-none rounded-[11px] px-6 py-[13px] bg-[#101828] text-white hover:bg-[#344054]">Download <svg viewBox="0 0 24 24" aria-hidden="true" class="size-[17px] shrink-0 fill-none stroke-current stroke-[2.2] transition-transform duration-[220ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none group-hover:translate-y-[3px] group-focus-visible:translate-y-[3px] motion-reduce:translate-y-0!"><path d="M12 4v11M7 11l5 5 5-5M5 20h14"/></svg></button>
<button type="button" class="group inline-flex cursor-pointer items-center gap-2.5 text-[.92rem] leading-[1.25] font-bold transition-[background-color,border-color,color] duration-[180ms] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#4f46e5] motion-reduce:transition-none rounded-[11px] px-6 py-[13px] border-[1.5px] border-[#858c98] bg-white text-[#344054] hover:border-[#344054]">Open docs <svg viewBox="0 0 24 24" aria-hidden="true" class="size-[17px] shrink-0 fill-none stroke-current stroke-[2.2] transition-transform duration-[220ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none group-hover:translate-x-0.5 group-hover:-translate-y-0.5 group-focus-visible:translate-x-0.5 group-focus-visible:-translate-y-0.5 motion-reduce:translate-none!"><path d="M14 5h5v5M19 5l-8 8M18 14v5H5V6h5"/></svg></button>
<button type="button" class="group inline-flex cursor-pointer items-center gap-2.5 text-[.92rem] leading-[1.25] font-bold transition-[background-color,border-color,color] duration-[180ms] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#4f46e5] motion-reduce:transition-none rounded-[11px] px-6 py-[13px] bg-[#e0f2fe] text-[#0369a1]">Refresh <svg viewBox="0 0 24 24" aria-hidden="true" class="size-[17px] shrink-0 fill-none stroke-current stroke-[2.2] transition-transform ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none duration-300 group-hover:rotate-180 group-focus-visible:rotate-180 motion-reduce:rotate-0!"><path d="M20 12a8 8 0 11-2.3-5.7"/><path d="M20 4v5h-5"/></svg></button>
<button type="button" class="group inline-flex cursor-pointer items-center gap-2.5 text-[.92rem] leading-[1.25] font-bold transition-[background-color,border-color,color] duration-[180ms] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#4f46e5] motion-reduce:transition-none size-11 justify-center rounded-full border-[1.5px] border-[#858c98] bg-transparent p-0 text-[#344054] hover:border-[#101828] hover:bg-[#101828] hover:text-white" aria-label="Next"><svg viewBox="0 0 24 24" aria-hidden="true" class="size-[17px] shrink-0 fill-none stroke-current stroke-[2.2] transition-transform duration-[220ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none group-hover:translate-x-[3px] group-focus-visible:translate-x-[3px] motion-reduce:translate-x-0!"><path d="M9 6l6 6-6 6"/></svg></button>

About this set

Five buttons whose icon moves in the direction of the action. Continue slides its arrow 5 pixels right, Download drops its arrow 3 pixels, Open docs nudges its external-link arrow up and to the right, and Refresh turns its circular arrow half a turn. The fifth is a round 44 pixel Next button with a chevron that fills dark on hover. The movement runs on hover and when the button gets keyboard focus, and uses a single transform on the SVG, so the label and button never shift. Use them for flow actions such as continuing a wizard, downloading a file, opening documentation in a new place or reloading data, where the motion reinforces what the button does. Icons are 17 pixel stroke SVGs drawn in currentColor, so they always match the label colour, including on hover. The white Open docs button and the round Next button have grey borders that reach 3:1 against the page, and every icon is hidden from screen readers. The Bootstrap version uses .btn with d-inline-flex, rounded-circle and colours set through –bs-btn-* variables; the Tailwind version uses group-hover and group-focus-visible.

What’s included

  • Arrow, download, external link, refresh and chevron icons that move
  • Movement on hover and on keyboard focus
  • Icons drawn in currentColor, matching the label
  • Round icon-only Next button with an aria-label
  • Icon movement disabled under reduced motion

Accessibility

Four buttons are named by their visible text and the round one by aria-label="Next"; every SVG is aria-hidden. All are native buttons reachable with Tab, and focus draws a 2px indigo outline 3px outside the button. Under prefers-reduced-motion the icons stay still and colour changes happen without a transition.

Customise it

In plain CSS change the colours on .ab-next, .ab-down, .ab-out, .ab-spin and .ab-circle and the distance in each svg transform. In Bootstrap set --bs-btn-* colours on the .btn-arrow-* classes; in Tailwind edit the bg- and text- utilities and the group-hover:translate-* values.