20 CSS Link Hover Effect Designs
Chevron Companion
On hover the underline retracts from right-to-left while a chevron arrow "draws in" via stroke-dasharray with a spring overshoot. Adapted from Aaron Iker — works on multi-line links thanks to background-image underline.
Chevron Companion the 5th of 20 designs in the 20 CSS Link Hover Effect Designs collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="cle-chev-bg">
<div class="cle-chev-stack">
<a href="#" class="cle-chev"
><span>Link here</span
><svg class="cle-chev-arrow" viewBox="0 0 13 20" aria-hidden="true">
<polyline points="0.5 19.5 3 19.5 12.5 10 3 0.5" /></svg
></a>
<a href="#" class="cle-chev cle-chev-multi"
><span>Link here with multiple lines</span
><svg class="cle-chev-arrow" viewBox="0 0 13 20" aria-hidden="true">
<polyline points="0.5 19.5 3 19.5 12.5 10 3 0.5" /></svg
></a>
</div>
</div> .cle-chev-bg {
padding: 28px 32px;
background: #f6f8ff;
border-radius: 10px;
}
.cle-chev-stack {
display: flex;
flex-direction: column;
gap: 22px;
align-items: flex-start;
}
.cle-chev {
--line: #646b8c;
--color: #2b3044;
--background-size: 100%;
--background-delay: 0.15s;
--stroke-dashoffset: 46;
--stroke-duration: 0.15s;
--stroke-easing: linear;
--stroke-delay: 0s;
position: relative;
display: inline;
color: var(--color);
font:
500 16px/20px "Inter",
system-ui,
sans-serif;
text-decoration: none;
}
.cle-chev span {
background-image: linear-gradient(0deg, var(--line) 0%, var(--line) 100%);
background-position: 100% 100%;
background-repeat: no-repeat;
background-size: var(--background-size) 1px;
transition: background-size 0.2s linear var(--background-delay);
transform: translateZ(0);
}
.cle-chev-arrow {
vertical-align: top;
display: inline;
line-height: 1;
width: 13px;
height: 20px;
position: relative;
left: -2px;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1px;
stroke: var(--line);
stroke-dasharray: 7.95 30;
stroke-dashoffset: var(--stroke-dashoffset);
transition: stroke-dashoffset var(--stroke-duration) var(--stroke-easing) var(--stroke-delay);
}
.cle-chev:hover,
.cle-chev:focus-visible {
--background-size: 0%;
--background-delay: 0s;
--stroke-dashoffset: 26;
--stroke-duration: 0.3s;
--stroke-easing: cubic-bezier(0.3, 1.5, 0.5, 1);
--stroke-delay: 0.195s;
}
.cle-chev-multi {
max-width: 180px;
}