Open demo

CSS code

HTML
<div><span class="lbl">Read more links</span><div class="row">
<a class="lk lk-slide" href="#"><span>Read the case study</span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="lk lk-reveal" href="#">View all 24 recipes<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="lk lk-grow" href="#">Compare plans<i aria-hidden="true"></i></a>
</div></div>
<div><span class="lbl">Previous and next article</span>
<nav class="pager" aria-label="More articles">
<a class="pg pg-prev" href="#" rel="prev"><span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M19 12H5M11 6l-6 6 6 6"/></svg></span><span><small>Previous</small><strong>Pricing pages that answer the second question</strong></span></a>
<a class="pg pg-next" href="#" rel="next"><span><small>Next</small><strong>What we learned rebuilding onboarding twice</strong></span><span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
</nav></div>
<div class="row">
<div><span class="lbl">Slider controls</span>
<div class="ctrl" role="group" aria-label="Customer stories">
<button type="button" class="cb" aria-label="Previous story" disabled><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button>
<span class="count"><b>01</b> / 08</span>
<button type="button" class="cb" aria-label="Next story"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
</div></div>
<div><span class="lbl">Arrow swap button</span>
<button type="button" class="cta">Start a free trial<span class="chip" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></button>
</div>
</div>
<div><span class="lbl">Link rows</span>
<div class="rows">
<a class="rw" href="#"><span>Careers<small>12 open roles</small></span><span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="rw" href="#"><span>Press kit<small>Logos, photos and boilerplate</small></span><span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="rw" href="#"><span>Status page<small>All systems normal</small></span><span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
</div></div>
CSS
/* Arrow buttons and links. Every arrow is an aria-hidden SVG or pseudo-element; the text, or an aria-label on
   icon-only buttons, gives the name. The arrow moves on hover and on keyboard focus; motion is off under reduced motion. */
.lk,.pager,.ctrl,.cta,.rows{--ink:#17142b;--accent:#4232d8;--accent-dark:#3427b8;--tint:#efedfd;--line:#e4e2ef;--muted:#5d5a72}
.lk svg,.pg svg,.cb svg,.cta svg,.rw svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform .28s cubic-bezier(.3,.7,.4,1),opacity .28s}
/* 1. Read more links */
.lk{display:inline-flex;align-items:center;gap:8px;border-radius:4px;color:var(--accent);font-size:.95rem;font-weight:650;text-decoration:none}
.lk:focus-visible{outline:2px solid var(--accent);outline-offset:4px}
.lk-slide span{padding-bottom:2px;background:linear-gradient(currentColor,currentColor) 0 100%/0 2px no-repeat;transition:background-size .3s}
.lk-slide:hover span,.lk-slide:focus-visible span{background-size:100% 2px}
.lk-slide:hover svg,.lk-slide:focus-visible svg{transform:translateX(4px)}
.lk-reveal svg{opacity:0;transform:translateX(-8px)}
.lk-reveal:hover svg,.lk-reveal:focus-visible svg{opacity:1;transform:none}
@media (hover:none){.lk-reveal svg{opacity:1;transform:none}}
.lk-grow i{position:relative;display:block;width:16px;height:12px;transition:width .3s cubic-bezier(.3,.7,.4,1)}
.lk-grow i::before{content:"";position:absolute;left:0;right:1px;top:5px;height:2px;border-radius:2px;background:currentColor}
.lk-grow i::after{content:"";position:absolute;right:1px;top:2px;width:8px;height:8px;border-top:2px solid currentColor;border-right:2px solid currentColor;rotate:45deg}
.lk-grow:hover i,.lk-grow:focus-visible i{width:30px}
/* 2. Previous / next article pager */
.pager{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.pg{display:flex;align-items:center;gap:14px;padding:18px 20px;border:1px solid var(--line);border-radius:14px;background:#fff;color:var(--ink);
  text-decoration:none;transition:border-color .2s,box-shadow .2s}
.pg:hover{border-color:#a9a1f5;box-shadow:0 8px 20px -10px rgba(66,50,216,.4)}
.pg:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.pg small{display:block;margin-bottom:4px;font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.pg strong{font-size:.95rem;line-height:1.35}
.pg-next{justify-content:flex-end;text-align:right}
.pg .ic{display:grid;place-items:center;flex:none;width:38px;height:38px;border-radius:50%;background:var(--tint);color:var(--accent)}
.pg-prev:hover svg,.pg-prev:focus-visible svg{transform:translateX(-4px)}
.pg-next:hover svg,.pg-next:focus-visible svg{transform:translateX(4px)}
/* 3. Slider controls */
.ctrl{display:inline-flex;align-items:center;gap:14px}
.cb{display:grid;place-items:center;width:46px;height:46px;padding:0;border:1.5px solid #7f7a9a;border-radius:50%;background:#fff;color:var(--ink);
  cursor:pointer;transition:background-color .2s,border-color .2s,color .2s}
.cb:hover:not(:disabled){border-color:var(--ink);background:var(--ink);color:#fff}
.cb:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.cb:disabled{opacity:.45;cursor:not-allowed}
.cb[aria-label^="Previous"]:hover:not(:disabled) svg{transform:translateX(-3px)}
.cb[aria-label^="Next"]:hover:not(:disabled) svg{transform:translateX(3px)}
.count{min-width:64px;text-align:center;font:600 .9rem ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
.count b{color:var(--ink)}
/* 4. Button whose arrow swaps out */
.cta{display:inline-flex;align-items:center;gap:14px;padding:7px 7px 7px 24px;border:0;border-radius:999px;background:var(--accent);color:#fff;
  font:inherit;font-size:.95rem;font-weight:650;cursor:pointer;transition:background-color .2s}
.cta:hover{background:var(--accent-dark)}
.cta:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.cta .chip{position:relative;width:36px;height:36px;overflow:hidden;border-radius:50%;background:#fff;color:var(--accent)}
.cta .chip svg{position:absolute;top:9px;left:9px;transition-duration:.38s}
.cta .chip svg+svg{transform:translateX(-36px)}
.cta:hover .chip svg,.cta:focus-visible .chip svg{transform:translateX(36px)}
.cta:hover .chip svg+svg,.cta:focus-visible .chip svg+svg{transform:none}
@media (max-width:600px){.pager{grid-template-columns:1fr}}
@media (prefers-reduced-motion:reduce){.lk,.pg,.cb,.cta,.rw .ic,.lk *,.pg *,.cb *,.cta *,.rw svg,.lk i::before{transition:none!important}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="arrows d-flex flex-column gap-5">
<div><span class="lbl">Read more links</span><div class="d-flex flex-wrap align-items-center column-gap-5 row-gap-3">
<a class="lk lk-slide icon-link icon-link-hover text-decoration-none" href="#"><span>Read the case study</span><svg class="bi" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="lk lk-reveal icon-link icon-link-hover text-decoration-none" href="#">View all 24 recipes<svg class="bi" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="lk lk-grow icon-link text-decoration-none" href="#">Compare plans<i aria-hidden="true"></i></a>
</div></div>
<div><span class="lbl">Previous and next article</span>
<nav class="row g-2 g-sm-3" aria-label="More articles">
<div class="col-12 col-sm-6"><a class="pg pg-prev card flex-row align-items-center gap-3 h-100 text-decoration-none" href="#" rel="prev"><span class="ic d-grid flex-shrink-0 rounded-circle" aria-hidden="true"><svg class="m-auto" viewBox="0 0 24 24"><path d="M19 12H5M11 6l-6 6 6 6"/></svg></span><span><small class="d-block mb-1 fw-semibold text-uppercase">Previous</small><strong>Pricing pages that answer the second question</strong></span></a></div>
<div class="col-12 col-sm-6"><a class="pg pg-next card flex-row align-items-center justify-content-end gap-3 h-100 text-end text-decoration-none" href="#" rel="next"><span><small class="d-block mb-1 fw-semibold text-uppercase">Next</small><strong>What we learned rebuilding onboarding twice</strong></span><span class="ic d-grid flex-shrink-0 rounded-circle" aria-hidden="true"><svg class="m-auto" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a></div>
</nav></div>
<div class="d-flex flex-wrap align-items-center column-gap-5 row-gap-4">
<div><span class="lbl">Slider controls</span>
<div class="d-inline-flex align-items-center gap-3" role="group" aria-label="Customer stories">
<button type="button" class="cb btn rounded-circle d-grid" aria-label="Previous story" disabled><svg class="m-auto" viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button>
<span class="count font-monospace fw-semibold text-center"><b>01</b> / 08</span>
<button type="button" class="cb btn rounded-circle d-grid" aria-label="Next story"><svg class="m-auto" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
</div></div>
<div><span class="lbl">Arrow swap button</span>
<button type="button" class="cta btn btn-primary rounded-pill d-inline-flex align-items-center gap-3">Start a free trial<span class="chip rounded-circle" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg><svg viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></button>
</div>
</div>
<div><span class="lbl">Link rows</span>
<div class="rows list-group list-group-flush">
<a class="rw list-group-item list-group-item-action d-flex align-items-center justify-content-between gap-3" href="#"><span>Careers<small>12 open roles</small></span><span class="ic d-grid flex-shrink-0 rounded-circle" aria-hidden="true"><svg class="m-auto" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="rw list-group-item list-group-item-action d-flex align-items-center justify-content-between gap-3" href="#"><span>Press kit<small>Logos, photos and boilerplate</small></span><span class="ic d-grid flex-shrink-0 rounded-circle" aria-hidden="true"><svg class="m-auto" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="rw list-group-item list-group-item-action d-flex align-items-center justify-content-between gap-3" href="#"><span>Status page<small>All systems normal</small></span><span class="ic d-grid flex-shrink-0 rounded-circle" aria-hidden="true"><svg class="m-auto" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
</div></div>
</div>
CSS
/* Bootstrap .icon-link-hover, .card, .btn and .list-group, recoloured through their --bs-* variables.
   Arrows are aria-hidden SVGs; icon-only buttons carry an aria-label. Motion is off under reduced motion. */
.arrows{--ink:#17142b;--accent:#4232d8;--accent-dark:#3427b8;--tint:#efedfd;--line:#e4e2ef;--muted:#5d5a72;
  --bs-link-color-rgb:66,50,216;--bs-link-hover-color-rgb:52,39,184}
.arrows svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform .28s cubic-bezier(.3,.7,.4,1),opacity .28s}
.arrows .icon-link>.bi{width:18px;height:18px;fill:none;transition:transform .28s cubic-bezier(.3,.7,.4,1)}
/* 1. Read more links */
.lk{gap:8px;border-radius:4px;font-size:.95rem;font-weight:650}
.lk:focus-visible{outline:2px solid var(--accent);outline-offset:4px;box-shadow:none}
.lk-slide{--bs-icon-link-transform:translateX(4px)}
.lk-slide span{padding-bottom:2px;background:linear-gradient(currentColor,currentColor) 0 100%/0 2px no-repeat;transition:background-size .3s}
.lk-slide:hover span,.lk-slide:focus-visible span{background-size:100% 2px}
.lk-reveal>.bi{opacity:0;transform:translateX(-8px)}
.lk-reveal:hover>.bi,.lk-reveal:focus-visible>.bi{opacity:1;transform:none}
@media (hover:none){.lk-reveal>.bi{opacity:1;transform:none}}
.lk-grow i{position:relative;display:block;width:16px;height:12px;transition:width .3s cubic-bezier(.3,.7,.4,1)}
.lk-grow i::before{content:"";position:absolute;left:0;right:1px;top:5px;height:2px;border-radius:2px;background:currentColor}
.lk-grow i::after{content:"";position:absolute;right:1px;top:2px;width:8px;height:8px;border-top:2px solid currentColor;border-right:2px solid currentColor;rotate:45deg}
.lk-grow:hover i,.lk-grow:focus-visible i{width:30px}
/* 2. Previous / next article pager on .card */
.pg{--bs-card-border-color:var(--line);--bs-card-border-radius:14px;padding:18px 20px;color:var(--ink);transition:border-color .2s,box-shadow .2s}
.pg:hover{border-color:#a9a1f5;box-shadow:0 8px 20px -10px rgba(66,50,216,.4)}
.pg:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.pg small{font-size:.7rem;letter-spacing:.1em;color:var(--muted)}
.pg strong{font-size:.95rem;line-height:1.35}
.pg .ic{width:38px;height:38px;background:var(--tint);color:var(--accent)}
.pg-prev:hover svg,.pg-prev:focus-visible svg{transform:translateX(-4px)}
.pg-next:hover svg,.pg-next:focus-visible svg{transform:translateX(4px)}
/* 3. Slider controls on .btn */
.cb{--bs-btn-color:var(--ink);--bs-btn-bg:#fff;--bs-btn-border-color:#7f7a9a;--bs-btn-border-width:1.5px;
  --bs-btn-hover-color:#fff;--bs-btn-hover-bg:var(--ink);--bs-btn-hover-border-color:var(--ink);
  --bs-btn-active-color:#fff;--bs-btn-active-bg:var(--ink);--bs-btn-active-border-color:var(--ink);
  --bs-btn-disabled-color:var(--ink);--bs-btn-disabled-bg:#fff;--bs-btn-disabled-border-color:#7f7a9a;--bs-btn-disabled-opacity:.45;
  width:46px;height:46px;padding:0}
.cb:focus-visible{outline:2px solid var(--accent);outline-offset:3px;box-shadow:none}
.cb[aria-label^="Previous"]:hover:not(:disabled) svg{transform:translateX(-3px)}
.cb[aria-label^="Next"]:hover:not(:disabled) svg{transform:translateX(3px)}
.count{min-width:64px;font-size:.9rem;color:var(--muted)}
.count b{color:var(--ink)}
/* 4. Button whose arrow swaps out */
.cta{--bs-btn-bg:var(--accent);--bs-btn-border-color:var(--accent);--bs-btn-hover-bg:var(--accent-dark);--bs-btn-hover-border-color:var(--accent-dark);
  --bs-btn-active-bg:var(--accent-dark);--bs-btn-active-border-color:var(--accent-dark);--bs-btn-font-weight:650;
  padding:7px 7px 7px 24px;font-size:.95rem}
.cta:focus-visible{outline:2px solid var(--accent);outline-offset:3px;box-shadow:none}
.cta .chip{position:relative;width:36px;height:36px;overflow:hidden;background:#fff;color:var(--accent)}
.cta .chip svg{position:absolute;top:9px;left:9px;transition-duration:.38s}
.cta .chip svg+svg{transform:translateX(-36px)}
.cta:hover .chip svg,.cta:focus-visible .chip svg{transform:translateX(36px)}
.cta:hover .chip svg+svg,.cta:focus-visible .chip svg+svg{transform:none}
/* 5. Link rows on .list-group-flush */
.rows{--bs-list-group-bg:transparent;--bs-list-group-border-color:var(--line);--bs-list-group-action-hover-bg:transparent;
  --bs-list-group-action-hover-color:var(--ink);--bs-list-group-action-active-bg:transparent;--bs-list-group-color:var(--ink);--bs-list-group-action-color:var(--ink);--bs-list-group-action-active-color:var(--ink);
  max-width:560px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.rw{padding:15px 4px;font-size:1.02rem;font-weight:650}
.rw small{margin-left:10px;font-size:.82rem;font-weight:500;color:var(--muted)}
.rw .ic{width:34px;height:34px;color:var(--accent);transition:background-color .2s,color .2s}
.rw svg{transform:rotate(-45deg)}
.rw:hover .ic,.rw:focus-visible .ic{background:var(--accent);color:#fff}
.rw:hover svg,.rw:focus-visible svg{transform:none}
.rw:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px;z-index:3}
@media (prefers-reduced-motion:reduce){.arrows *,.arrows *::before,.arrows *::after{transition:none!important}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-muted uppercase">Read more links</span><div class="flex flex-wrap items-center gap-x-[34px] gap-y-5">
<a class="group inline-flex items-center gap-2 rounded text-[.95rem] font-[650] text-accent focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-accent" href="#"><span class="bg-linear-to-r from-current to-current bg-[length:0_2px] bg-bottom-left bg-no-repeat pb-0.5 transition-[background-size] duration-300 group-hover:bg-[length:100%_2px] group-focus-visible:bg-[length:100%_2px] motion-reduce:transition-none">Read the case study</span><svg class="size-[18px] flex-none fill-none stroke-current stroke-[2.2] transition-transform duration-[280ms] ease-arrow group-hover:translate-x-1 group-focus-visible:translate-x-1 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="group inline-flex items-center gap-2 rounded text-[.95rem] font-[650] text-accent focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-accent" href="#">View all 24 recipes<svg class="size-[18px] flex-none -translate-x-2 fill-none stroke-current stroke-[2.2] opacity-0 transition-[opacity,translate] duration-[280ms] ease-arrow group-hover:translate-x-0 group-hover:opacity-100 group-focus-visible:translate-x-0 group-focus-visible:opacity-100 pointer-coarse:translate-x-0 pointer-coarse:opacity-100 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
<a class="group inline-flex items-center gap-2 rounded text-[.95rem] font-[650] text-accent focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-accent" href="#">Compare plans<span aria-hidden="true" class="relative block h-3 w-4 transition-[width] duration-300 ease-arrow group-hover:w-[30px] group-focus-visible:w-[30px] motion-reduce:transition-none before:absolute before:top-[5px] before:right-px before:left-0 before:h-0.5 before:rounded-sm before:bg-current before:content-[''] after:absolute after:top-0.5 after:right-px after:size-2 after:rotate-45 after:border-t-2 after:border-r-2 after:border-current after:content-['']"></span></a>
</div></div>
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-muted uppercase">Previous and next article</span>
<nav class="grid grid-cols-1 gap-3 sm:grid-cols-2" aria-label="More articles">
<a class="group flex items-center gap-3.5 rounded-[14px] border border-line bg-white px-5 py-[18px] text-ink transition-[border-color,box-shadow] duration-200 hover:border-[#a9a1f5] hover:shadow-[0_8px_20px_-10px_rgba(66,50,216,.4)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent motion-reduce:transition-none" href="#" rel="prev"><span class="grid size-[38px] flex-none place-items-center rounded-full bg-tint text-accent" aria-hidden="true"><svg class="size-[18px] fill-none stroke-current stroke-[2.2] transition-transform duration-[280ms] ease-arrow group-hover:-translate-x-1 group-focus-visible:-translate-x-1 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M19 12H5M11 6l-6 6 6 6"/></svg></span><span><small class="mb-1 block text-[.7rem] font-semibold tracking-[.1em] text-muted uppercase">Previous</small><strong class="text-[.95rem] leading-[1.35]">Pricing pages that answer the second question</strong></span></a>
<a class="group flex items-center justify-end gap-3.5 rounded-[14px] border border-line bg-white px-5 py-[18px] text-right text-ink transition-[border-color,box-shadow] duration-200 hover:border-[#a9a1f5] hover:shadow-[0_8px_20px_-10px_rgba(66,50,216,.4)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent motion-reduce:transition-none" href="#" rel="next"><span><small class="mb-1 block text-[.7rem] font-semibold tracking-[.1em] text-muted uppercase">Next</small><strong class="text-[.95rem] leading-[1.35]">What we learned rebuilding onboarding twice</strong></span><span class="grid size-[38px] flex-none place-items-center rounded-full bg-tint text-accent" aria-hidden="true"><svg class="size-[18px] fill-none stroke-current stroke-[2.2] transition-transform duration-[280ms] ease-arrow group-hover:translate-x-1 group-focus-visible:translate-x-1 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
</nav></div>
<div class="flex flex-wrap items-center gap-x-[34px] gap-y-5">
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-muted uppercase">Slider controls</span>
<div class="inline-flex items-center gap-3.5" role="group" aria-label="Customer stories">
<button type="button" class="group grid size-[46px] cursor-pointer place-items-center rounded-full border-[1.5px] border-[#7f7a9a] bg-white text-ink transition-colors duration-200 enabled:hover:border-ink enabled:hover:bg-ink enabled:hover:text-white focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent disabled:cursor-not-allowed disabled:opacity-45 motion-reduce:transition-none" aria-label="Previous story" disabled><svg class="size-[18px] fill-none stroke-current stroke-[2.2] transition-transform duration-[280ms] group-enabled:group-hover:-translate-x-[3px] motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button>
<span class="min-w-16 text-center font-mono text-[.9rem] font-semibold text-muted"><b class="text-ink">01</b> / 08</span>
<button type="button" class="group grid size-[46px] cursor-pointer place-items-center rounded-full border-[1.5px] border-[#7f7a9a] bg-white text-ink transition-colors duration-200 enabled:hover:border-ink enabled:hover:bg-ink enabled:hover:text-white focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent disabled:cursor-not-allowed disabled:opacity-45 motion-reduce:transition-none" aria-label="Next story"><svg class="size-[18px] fill-none stroke-current stroke-[2.2] transition-transform duration-[280ms] group-enabled:group-hover:translate-x-[3px] motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
</div></div>
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-muted uppercase">Arrow swap button</span>
<button type="button" class="group inline-flex cursor-pointer items-center gap-3.5 rounded-full bg-accent py-[7px] pr-[7px] pl-6 text-[.95rem] font-[650] text-white transition-colors duration-200 hover:bg-accent-dark focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent motion-reduce:transition-none">Start a free trial<span class="relative size-9 overflow-hidden rounded-full bg-white text-accent" aria-hidden="true"><svg class="absolute top-[9px] left-[9px] size-[18px] fill-none stroke-current stroke-[2.2] transition-transform duration-[380ms] ease-arrow group-hover:translate-x-9 group-focus-visible:translate-x-9 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg><svg class="absolute top-[9px] left-[9px] size-[18px] -translate-x-9 fill-none stroke-current stroke-[2.2] transition-transform duration-[380ms] ease-arrow group-hover:translate-x-0 group-focus-visible:translate-x-0 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></button>
</div>
</div>
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-muted uppercase">Link rows</span>
<div class="grid max-w-[560px] border-t border-line">
<a class="group flex items-center justify-between gap-4 border-b border-line px-1 py-[15px] text-[1.02rem] font-[650] text-ink focus-visible:rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent" href="#"><span>Careers<small class="ml-2.5 text-[.82rem] font-medium text-muted">12 open roles</small></span><span class="grid size-[34px] flex-none place-items-center rounded-full text-accent transition-colors duration-200 group-hover:bg-accent group-hover:text-white group-focus-visible:bg-accent group-focus-visible:text-white motion-reduce:transition-none" aria-hidden="true"><svg class="size-[18px] -rotate-45 fill-none stroke-current stroke-[2.2] transition-[rotate] duration-[280ms] ease-arrow group-hover:rotate-0 group-focus-visible:rotate-0 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="group flex items-center justify-between gap-4 border-b border-line px-1 py-[15px] text-[1.02rem] font-[650] text-ink focus-visible:rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent" href="#"><span>Press kit<small class="ml-2.5 text-[.82rem] font-medium text-muted">Logos, photos and boilerplate</small></span><span class="grid size-[34px] flex-none place-items-center rounded-full text-accent transition-colors duration-200 group-hover:bg-accent group-hover:text-white group-focus-visible:bg-accent group-focus-visible:text-white motion-reduce:transition-none" aria-hidden="true"><svg class="size-[18px] -rotate-45 fill-none stroke-current stroke-[2.2] transition-[rotate] duration-[280ms] ease-arrow group-hover:rotate-0 group-focus-visible:rotate-0 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
<a class="group flex items-center justify-between gap-4 border-b border-line px-1 py-[15px] text-[1.02rem] font-[650] text-ink focus-visible:rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent" href="#"><span>Status page<small class="ml-2.5 text-[.82rem] font-medium text-muted">All systems normal</small></span><span class="grid size-[34px] flex-none place-items-center rounded-full text-accent transition-colors duration-200 group-hover:bg-accent group-hover:text-white group-focus-visible:bg-accent group-focus-visible:text-white motion-reduce:transition-none" aria-hidden="true"><svg class="size-[18px] -rotate-45 fill-none stroke-current stroke-[2.2] transition-[rotate] duration-[280ms] ease-arrow group-hover:rotate-0 group-focus-visible:rotate-0 motion-reduce:transition-none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a>
</div></div>
CSS
/* Palette for the arrow links and buttons. Everything else is utilities; arrows are aria-hidden SVGs or spans. */
@theme {
  --color-ink: #17142b;
  --color-accent: #4232d8;
  --color-accent-dark: #3427b8;
  --color-tint: #efedfd;
  --color-line: #e4e2ef;
  --color-muted: #5d5a72;
  --ease-arrow: cubic-bezier(.3,.7,.4,1);
}

About this set

Arrow links and buttons for the places arrows usually appear in a product: read more links, article navigation, carousels and calls to action. The read more row has three behaviours: an arrow that slides while an underline grows under the text, an arrow that appears only on hover or focus (and is always shown on touch screens, where there is no hover), and a line arrow whose shaft grows longer. The previous and next pager is a nav of two cards with rel=”prev” and rel=”next” whose arrows move outward. The slider controls pair two circular icon buttons with a 01 / 08 counter, with the first button disabled. The arrow swap button sends its arrow out of a white chip while a second arrow slides in. The link rows turn a diagonal arrow straight and fill its circle on hover, a pattern for footer or settings links. Arrows are aria-hidden SVGs, so links are named by their words and the icon-only buttons by aria-label. Every movement is triggered by keyboard focus as well as hover. The Bootstrap version uses .icon-link-hover, .card, .btn and .list-group.

What’s included

  • Three read more link behaviours: slide, reveal and growing shaft
  • Previous and next article pager with rel="prev" and rel="next"
  • Slider controls with labelled icon buttons and a disabled state
  • Arrow swap button and link rows with turning arrows
  • Bootstrap version built on .icon-link-hover, .card, .btn and .list-group

Accessibility

Arrows are aria-hidden, so links and buttons are named by their text, and the icon-only slider buttons have aria-label="Previous story" and "Next story". Every arrow movement that happens on hover also happens on :focus-visible, and each control shows a 2px indigo outline. The hidden arrow on the reveal link is always visible on touch screens. Transitions are removed under prefers-reduced-motion.

Customise it

Change --accent, --ink, --tint, --line and --muted on the components in plain CSS. In Bootstrap the same variables sit on .arrows next to --bs-link-color-rgb and the --bs-btn-* and --bs-list-group-* variables; in Tailwind edit the colours in @theme.