button.button.red.shine
  span(data-title="One") One
button.button.green.shine
  span(data-title="Two") Two
button.button.blue.shine
  span(data-title="Three") Three
View Compiled
body {
  min-height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1em;
}

button {
  padding: 1em 2em;
  font-size: 2em;
  border: 0px;
  transition: all 0.3s cubic-bezier(0, 1.22, 0.67, 1.17);
  border-radius: 1em;
  box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0);
  position: relative;
  transform-style: preserve-3d;
  box-shadow: 0.5em 0.5em 1em 0 rgba(0, 0, 0, 0), 0 -3px 0 0 rgba(0, 0, 0, 0.15) inset;
  transform: scale(var(--s, 1)) rotateX(calc(((var(--y) - 50) * -1) * 0.25deg))
    rotateY(calc(((var(--x) - 50)) * 0.25deg)) translateZ(var(--z, .1em));
  &::before,
  &::after {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 50%;
    top: 50%;
    display: block;
    content: "";
    transform: translate(-50%, -50%);
  }
  &::after { // This one is extra big, just for the event to be triggered faster when closer to the button.
    width: calc(100% + 2em);
    height: calc(100% + 2em);
  }

  &::before {
    background-image: linear-gradient(
      to right bottom,
      transparent 25%,
      rgba(255, 255, 255, 0.25),
      transparent 75%
    );
    background-size: 200% 200%;
    background-position: calc(var(--x) * 1%) calc(var(--y) * 1%);
    transform: translate(-50%, -50%);
    transition: all 0.3s cubic-bezier(0, 1.22, 0.67, 1.17);
    border-radius: inherit;
    // box-shadow: 2em 2em 3em 0 rgba(0, 0, 0, 0.1) inset;
  }
  &.red {
    background-color: rgba(255, 125, 125, 0.5);
    color: rgba(127,62,62,0.5);
  }
  &.green {
    background-color: rgba(0, 255, 125, 0.5);
    color: rgba(0,127,62,0.5);
  }
  &.blue {
    background-color: rgba(0, 125, 255, 0.5);
   color: rgba(0,62,127,0.5);
  }    
  span{
    position: relative;
    z-index: 1;
    display: block;
     transform: translateZ(0em);
    transition: all 0.3s ease-in-out;  transform-style: preserve-3d;
    &::before{    
      transition: all 0.3s ease-in-out;  transform-style: preserve-3d;

  position: absolute;
     transform: translate(-1px, -1px) translateZ(0em);
      color: white;
      content: attr(data-title);
    }
  }
  &:hover {
    --s: 1.05;
    --z: 1em;
    box-shadow: 0.5em 0.5em 1em 0 rgba(0, 0, 0, 0.1), 0 -3px 0 0 rgba(0, 0, 0, 0.15) inset;
    span::before{
      transform: translate(-1px, -1px)  translateZ(1em);
    }
  }
}
View Compiled
let y = 50;
let x = 50;

const reset = (element) => {
  y = 50;
  x = 50;
  console.log(reset);
  element.setAttribute("data-x", x);
  element.setAttribute("data-y", y);
  element.style.setProperty("--x", x);
  element.style.setProperty("--y", y);
};
const shineItUp = (element) => {
  const rect = element.getBoundingClientRect();
  const data = {
    top: rect.top,
    left: rect.left,
    bottom: rect.top + rect.height,
    right: rect.left + rect.width,
    width: rect.width,
    height: rect.height
  };

  element.addEventListener("mouseout", () => {
    reset(element);
  });
  element.addEventListener("mousemove", (e) => {
    if (
      e.clientX + 20 >= data.left &&
      e.clientX - 20 <= data.right &&
      e.clientY + 20 >= data.top &&
      e.clientY - 20 <= data.bottom
    ) {
      x = Math.round((100 / data.width) * (e.clientX - data.left));
      y = Math.round((100 / data.height) * (e.clientY - data.top));
      element.setAttribute("data-x", x);
      element.setAttribute("data-y", y);
      element.style.setProperty("--x", x);
      element.style.setProperty("--y", y);
    } else {
      reset(element);
    }
  });
};

const shiners = document.querySelectorAll(".shine");
shiners.forEach((shiner) => {
  shineItUp(shiner);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.