JSFiddle - React, Tailwind, and code Playground
by Kenneth Luplau-Brøgger
HTML
<div class="piano">
<div class="octave">
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
</div>
<div class="octave">
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
<div class="key half"></div>
<div class="key"></div>
</div>
</div>
SCSS
:root {
--keyWidth: 14.2857142857%;
--halfNoteOffset: 33.3%;
}
.piano {
font-size: 0;
margin: 1rem auto 2rem auto;
position: relative;
white-space: nowrap;
}
.octave {
position: relative;
white-space: nowrap;
width: 600px;
height: 400px;
display: inline-block;
.key {
font-size: 1rem;
height: 100%;
width: var(--keyWidth);
display: inline-block;
border-radius: 0 0 1rem 1rem;
overflow: hidden;
z-index: 2;
box-shadow: 0 0.5rem 0.5rem rgba(0, 0, 0, 0.08), inset 0 0 2px rgba(0, 0, 0, 0.3), inset 0 -2rem 0 -0.5rem rgb(235, 235, 235);
&:active {
background: linear-gradient(180deg, rgba(250, 250, 250, 1) 0%, rgba(255, 255, 255, 1) 100%);
transform-origin: 50% 0%;
box-shadow: inset 0.1rem 0 1rem rgba(0, 0, 0, 0.1), inset 0 -1rem 0 -0.35rem rgb(230, 230, 230);
z-index: 1;
}
&.half {
position: absolute;
background: black;
height: 65%;
vertical-align: top;
width: calc(var(--keyWidth) * 0.6);
box-shadow: 0.5rem 0.25rem 1rem rgba(0, 0, 0, 0.52), 0rem 0.25rem 0.15rem rgba(0, 0, 0, 0.2), inset 0 -1rem 0 0.3rem rgb(33, 33, 33);
&::after {
content: "";
position: absolute;
width: 80%;
height: 1.3rem;
left: 10%;
bottom: 0;
background: white;
border-radius: 4rem;
opacity: 0.08;
}
&:nth-of-type(2),
&:nth-of-type(7){
transform: translateX(calc(-100% + var(--halfNoteOffset)));
}
&:nth-of-type(4),
&:nth-of-type(11) {
transform: translateX(calc(var(--halfNoteOffset) * -1));
}
&:nth-of-type(9){
transform: translateX(-50%);
}
&:active {
background: linear-gradient(180deg, rgba(10, 10, 10, 1) 0%, rgba(0, 0, 0, 1) 100%);
box-shadow: 0.5rem 0.25rem 0.5rem rgba(0, 0, 0, 0.2), 0rem 0.15rem 0.15rem rgba(0, 0, 0, 0.1), inset 0 -0.5rem 0 0.3rem...