JSFiddle - React, Tailwind, and code Playground
by davidxmartins
HTML
<button class="arrow-btn">
<span>Hover me</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.7 21.36">
<defs>
<style>
.cls-1 {
stroke-width: 2.25px;
}
.send-arrow_head, .send-arrow_body {
fill: none;
stroke: #fff;
stroke-linecap: round;
stroke-linejoin: round;
}
.cls-2 {
stroke-width: 2.5px;
}
</style>
</defs>
<line class="send-arrow_body" x1="19.15" y1="10.68" x2="1.25" y2="10.68"/>
<polyline class="send-arrow_head" points="11.02 1.13 20.58 10.68 11.02 20.23"/>
</svg>
</button>
CSS
.arrow-btn {
/* Core styles */
display: inline-block;
position: relative;
padding: 1.4rem 4.2rem 1.4rem 2.1rem; /* extra right padding for arrow space */
min-width: 200px;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 1.5px;
color: white;
background: #1d1d1d;
border: 2px solid #1d1d1d;
cursor: pointer;
overflow: hidden;
transition: background 0.3s, border-color 0.3s;
}
.arrow-btn:hover {
background: #282828;
border-color: #282828;
}
/* Text slides left on hover */
.arrow-btn span {
display: inline-block;
transition: transform 0.35s cubic-bezier(0.16, 0.08, 0.355, 1);
}
.arrow-btn:hover span {
transform: translateX(-18px); /* adjust this value if you want more/less slide */
}
/* Arrow - starts hidden on the right */
.arrow-btn svg {
position: absolute;
top: 50%;
right: 2.1rem; /* matches the extra right padding */
width: 1.1em;
height: 1.1em;
opacity: 0;
transform: translateY(-50%);
stroke: white;
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
transition: opacity 0.35s, transform 0.35s cubic-bezier(0.16, 0.08, 0.355, 1);
pointer-events: none; /* prevents arrow from blocking hover */
}
.arrow-btn:hover svg {
opacity: 1;
transform: translateY(-50%) translateX(-20px); /* flies in from the right */
}