<div class="case">
	<!-- 1 row -->
  <div class="key" data-key="prtSc"></div>
  <div class="key" data-key="scrLk"></div>
  <div class="key" data-key="break"></div>

	<!-- 2 row -->
  <div class="key" data-key="ins"></div>
  <div class="key" data-key="home"></div>
  <div class="key" data-key="pgUp"></div>
	<!-- 3 row -->
  <div class="key" data-key="del"></div>
  <div class="key" data-key="end"></div>
  <div class="key" data-key="pgDn"></div>
	<!-- 4 row -->
  <div class="gap"></div>
  <div class="gap"></div>
  <div class="gap"></div>
  <div class="gap"></div>
  <div class="gap"></div>
  <div class="gap"></div>
  <div class="gap"></div>
	<!-- 5 row -->
  <div class="gap"></div>
  <div class="key" data-key="arrowUp">▲</div>
	<div class="gap"></div>
  <!-- 6 row -->
  
  <div class="key" data-key="arrowLeft">◀</div>
  <div class="key" data-key="arrowDown">▼</div>
  <div class="key" data-key="arrowRight">▶</div>
  
</div>
body {
  background-color: #625499;
  display: table-cell;
  height: 100vh;
  margin: 0;
  text-align: center;
  vertical-align: middle;
  width: 100vw;
}

.case {
  background-color: #463973;
  border-color: #2e2640;
  border-radius: 5px;
  border-style: solid;
  border-width: 8px 10px 15px 10px;
  display: inline-grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(6, 1fr);
  height: 20em;
  padding: 5px;
  user-select: none;
  width: 10em;
}

.key {
  border-color: #382e59 #2e2640;
  border-radius: 2px;
  border-style: solid;
  border-width: 3px 5px 8px 5px;
  color: #bbadd9;
  display: block;
  font-family: sans-serif;
  font-size: 7px;
  font-weight: 800;
  grid-column-end: span 2;
  margin: 3px;
  padding-top: 2px;
  padding: 5px;
  text-align: center;
  text-transform: uppercase;
  transition: all 50ms ease-out;
  will-change: box-shadow, color, text-shadow;
}

.key:empty::before {
  content: attr(data-key);
}

.active {
  transform: perspective(1200px) translateZ(-90px);
}

.medium {
  grid-column-end: span 3;
}

.large {
  grid-column-end: span 4;
}

.xl {
  grid-column-end: span 5;
}

.xxl {
  grid-column-end: span 6;
}

.xxxl {
  grid-column-end: 7;
}

.huge {
  grid-column-end: span 12;
}
const keysArr = [...document.querySelectorAll(".key")];

const getKey = (event) => {
  const parsedKey = event.key.toLowerCase().replace("\\", "\\\\");
  const parsedCode = event.code.toLowerCase();
  const element =
    document.querySelector(`[data-key="${parsedCode}"]`) ||
    document.querySelector(`[data-key="${parsedKey}"]`);

  return element;
};

document.addEventListener("keydown", (event) => {
  const key = getKey(event);
  if (key) {
    key.classList.add("active");
  }
});

document.addEventListener("keyup", (event) => {
  const key = getKey(event);
  if (key) {
    key.classList.remove("active");
  }
});

document.addEventListener("mousedown", (event) => {
  if (event.target.dataset.key) {
    event.target.classList.add("active");
  }
});

document.addEventListener("mouseup", (event) => {
  if (event.target.dataset.key) {
    event.target.classList.remove("active");
  }
});

document.addEventListener("touchstart", (event) => {
  if (event.target.dataset.key) {
    event.target.classList.add("active");
  }
});

document.addEventListener("touchend", (event) => {
  if (event.target.dataset.key) {
    event.target.classList.remove("active");
  }
});

const animate = (element) => {
  const hueColor = Math.floor(Math.random() * (360 - 0 + 1)) + 0;
  const color = `hsla(${hueColor}, 100%, 50%, 50%)`;
  const textColor = `hsl(${hueColor}, 100%, 50%)`;
  const textShadow = `0 0 0.80em ${color}, 0 0 1.60em ${color}, 0 0 4em ${color}`;
  const boxShadow = `-3px 3px 4px ${color}, 3px -3px 4px ${color}, 3px 3px 4px ${color}, -3px -3px 4px ${color}, 0 0 10px ${color}`;

  const keyIndex = keysArr.indexOf(element);
  const animatedKeysRight = keysArr.slice(keyIndex);
  const animatedKeysLeft = keysArr.slice(0, keyIndex);

  const transitionHandler = (event) => {
    event.target.style.boxShadow = "none";
    event.target.style.color = null;
    event.target.style.textShadow = "none";
    event.target.removeEventListener("transitionend", transitionHandler);
  };

  animatedKeysRight.forEach((keyEl, i) => {
    setTimeout(() => {
      keyEl.addEventListener("transitionend", transitionHandler);
      keyEl.style.boxShadow = boxShadow;
      keyEl.style.color = textColor;
      keyEl.style.textShadow = textShadow;
    }, i * 35);
  });

  animatedKeysLeft.forEach((keyEl, j) => {
    const i = animatedKeysLeft.length - j;
    setTimeout(() => {
      keyEl.addEventListener("transitionend", transitionHandler);
      keyEl.style.boxShadow = boxShadow;
      keyEl.style.color = textColor;
      keyEl.style.textShadow = textShadow;
    }, i * 35);
  });
};

document.addEventListener("keydown", (event) => {
  const key = getKey(event);

  if (key) {
    animate(key);
  }
});

document.addEventListener("click", (event) => {
  if (event.target.dataset.key) {
    animate(event.target);
  }
});

window.addEventListener("load", () => {
  const key = document.querySelector(`[data-key="enter"]`);
  animate(key);
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.