<ul id="piano">
  <li data-note="C4" class="key">
    <div data-note="C#4" class="black-key">R</div>
    D
  </li>
  <li data-note="D4" class="key">
    <div data-note="D#4" class="black-key">T</div>
    F
  </li>
  <li data-note="E4" class="key">
    G
  </li>
  <li data-note="F4" class="key">
    <div data-note="F#4" class="black-key">U</div>
    H
  </li>
  <li data-note="G4" class="key">
    <div data-note="G#4" class="black-key">I</div>
    J
  </li>
  <li data-note="A4" class="key">
    <div data-note="A#4" class="black-key">O</div>
    K
  </li>
  <li data-note="B4" class="key">
    L
  </li>
</ul>
@import url('https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap');
 body {
	 font-family: 'Roboto', sans-serif;
	 display: flex;
	 justify-content: center;
	 align-items: center;
	 min-height: 100vh;
}
 ul {
	 list-style: none;
	 display: flex;
}
 ul .key {
	 position: relative;
	 width: 60px;
	 height: 180px;
	 border: 1px solid black;
	 border-right: none;
	 background: #fffff0;
	 border-radius: 5px;
	 box-shadow: 0px 3px 5px #666;
	 cursor: pointer;
	 display: flex;
	 justify-content: center;
	 align-items: flex-end;
	 padding-bottom: 10px;
	 font-weight: bold;
}
 ul .key:last-child {
	 border-right: 1px solid black;
}
 ul .black-key {
	 position: absolute;
	 top: -1px;
	 left: 37.5px;
	 width: 45px;
	 height: 120px;
	 background: black;
	 border-radius: 5px;
	 box-shadow: 0px 3px 5px #666;
	 z-index: 999;
	 display: flex;
	 justify-content: center;
	 align-items: flex-end;
	 padding-bottom: 10px;
	 color: white;
}
 ul .active {
	 box-shadow: 0px 1px 3px #666;
}
 
View Compiled
const synth = new Tone.Synth();
synth.oscillator.type = "sine";
synth.toMaster();

const piano = document.getElementById("piano");

piano.addEventListener("mousedown", e => {
  synth.triggerAttack(e.target.dataset.note);
});

piano.addEventListener("mouseup", e => {
  synth.triggerRelease();
});

document.addEventListener("keydown", e => {
  switch (e.key) {
    case "d":
      return synth.triggerAttack("C4");
    case "r":
      return synth.triggerAttack("C#4");
    case "f":
      return synth.triggerAttack("D4");
    case "t":
      return synth.triggerAttack("D#4");
    case "g":
      return synth.triggerAttack("E4");
    case "h":
      return synth.triggerAttack("F4");
    case "u":
      return synth.triggerAttack("F#4");
    case "j":
      return synth.triggerAttack("G4");
    case "i":
      return synth.triggerAttack("G#4");
    case "k":
      return synth.triggerAttack("A4");
    case "o":
      return synth.triggerAttack("A#4");
    case "l":
      return synth.triggerAttack("B4");
    default:
      return;
  }
});

document.addEventListener("keyup", e => {
  switch (e.key) {
    case "d":
    case "r":
    case "f":
    case "t":
    case "g":
    case "h":
    case "u":
    case "j":
    case "i":
    case "k":
    case "o":
    case "l":
       synth.triggerRelease(); 
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/tone@latest/build/Tone.js