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 */
}