<div class="case">
<!-- First row -->
<div class="key" data-key="escape">esc</div>
<div class="key" data-key="1"></div>
<div class="key" data-key="2"></div>
<div class="key" data-key="3"></div>
<div class="key" data-key="4"></div>
<div class="key" data-key="5"></div>
<div class="key" data-key="6"></div>
<div class="key" data-key="7"></div>
<div class="key" data-key="8"></div>
<div class="key" data-key="9"></div>
<div class="key" data-key="0"></div>
<div class="key" data-key="-"></div>
<div class="key" data-key="="></div>
<div class="key xxl" data-key="backspace"></div>
<div class="key" data-key="help">ins</div>
<div class="key" data-key="home"></div>
<!-- Second row -->
<div class="key large" data-key="tab"></div>
<div class="key" data-key="q"></div>
<div class="key" data-key="w"></div>
<div class="key" data-key="e"></div>
<div class="key" data-key="r"></div>
<div class="key" data-key="t"></div>
<div class="key" data-key="y"></div>
<div class="key" data-key="u"></div>
<div class="key" data-key="i"></div>
<div class="key" data-key="o"></div>
<div class="key" data-key="p"></div>
<div class="key" data-key="["></div>
<div class="key" data-key="]"></div>
<div class="key large" data-key="\"></div>
<div class="key" data-key="delete">del</div>
<div class="key" data-key="end"></div>
<!-- Third row -->
<div class="key xl" data-key="capslock">caps</div>
<div class="key" data-key="a"></div>
<div class="key" data-key="s"></div>
<div class="key" data-key="d"></div>
<div class="key" data-key="f"></div>
<div class="key" data-key="g"></div>
<div class="key" data-key="h"></div>
<div class="key" data-key="j"></div>
<div class="key" data-key="k"></div>
<div class="key" data-key="l"></div>
<div class="key" data-key=";"></div>
<div class="key" data-key="'"></div>
<div class="key xl" data-key="enter">return</div>
<div class="key" data-key="f15">pause</div>
<div class="key" data-key="pageup">pg up</div>
<!-- Fourth row -->
<div class="key xxl" data-key="shiftleft">shift</div>
<div class="key" data-key="z"></div>
<div class="key" data-key="x"></div>
<div class="key" data-key="c"></div>
<div class="key" data-key="v"></div>
<div class="key" data-key="b"></div>
<div class="key" data-key="n"></div>
<div class="key" data-key="m"></div>
<div class="key" data-key=","></div>
<div class="key" data-key="."></div>
<div class="key" data-key="/"></div>
<div class="key xxl" data-key="shiftright">shift</div>
<div class="key" data-key="arrowup">▲</div>
<div class="key" data-key="pagedown">pg dn</div>
<!-- Fifth row -->
<div class="key medium" data-key="controlleft">ctrl</div>
<div class="key medium" data-key="meta">win</div>
<div class="key medium" data-key="altleft">alt</div>
<div class="key huge" data-key=" "></div>
<div class="key medium" data-key="altright">alt</div>
<div class="key medium" data-key="fn"></div>
<div class="key medium" data-key="controlright">ctrl</div>
<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(36, 1fr);
grid-template-rows: repeat(5, 1fr);
height: 17em;
padding: 5px;
user-select: none;
width: 60em;
}
.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: 9px;
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);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.