<div class="keyboard">
  <div class="row">
    <kbd tabindex=1 data-key="`" data-alt="~"></kbd>
    <kbd data-key="1" data-alt="!"></kbd>
    <kbd data-key="2" data-alt="@"></kbd>
    <kbd data-key="3" data-alt="#"></kbd>
    <kbd data-key="4" data-alt="$"></kbd>
    <kbd data-key="5" data-alt="%"></kbd>
    <kbd data-key="6" data-alt="^"></kbd>
    <kbd data-key="7" data-alt="&"></kbd>
    <kbd data-key="8" data-alt="*"></kbd>
    <kbd data-key="9" data-alt="("></kbd>
    <kbd data-key="0" data-alt=")"></kbd>
    <kbd data-key="-" data-alt="_"></kbd>
    <kbd data-key="=" data-alt="+"></kbd>
    <kbd data-key="backspace"></kbd>
  </div>
  <div class="row">
    <kbd data-key="tab"></kbd>
    <kbd data-key="q"></kbd>
    <kbd data-key="w"></kbd>
    <kbd data-key="e"></kbd>
    <kbd data-key="r"></kbd>
    <kbd data-key="t"></kbd>
    <kbd data-key="y"></kbd>
    <kbd data-key="u"></kbd>
    <kbd data-key="i"></kbd>
    <kbd data-key="o"></kbd>
    <kbd data-key="p"></kbd>
    <kbd data-key="[" data-alt="{"></kbd>
    <kbd data-key="]" data-alt="}"></kbd>
    <kbd data-key="\" data-alt="|" id='backslash'></kbd>
  </div>
  <div class="row">
    <kbd data-key="caps"></kbd>
    <kbd data-key="a"></kbd>
    <kbd data-key="s"></kbd>
    <kbd data-key="d"></kbd>
    <kbd data-key="f"></kbd>
    <kbd data-key="g"></kbd>
    <kbd data-key="h"></kbd>
    <kbd data-key="j"></kbd>
    <kbd data-key="k"></kbd>
    <kbd data-key="l"></kbd>
    <kbd data-key=";" data-alt=":"></kbd>
    <kbd data-key="'" data-alt='"' id='quote'></kbd>
    <kbd data-key="enter"></kbd>
  </div>
  <div class="row">
    <kbd data-key="lshift"></kbd>
    <kbd data-key="z"></kbd>
    <kbd data-key="x"></kbd>
    <kbd data-key="c"></kbd>
    <kbd data-key="v"></kbd>
    <kbd data-key="b"></kbd>
    <kbd data-key="n"></kbd>
    <kbd data-key="m"></kbd>
    <kbd data-key="," data-alt="<"></kbd>
    <kbd data-key="." data-alt=">"></kbd>
    <kbd data-key="/" data-alt="?"></kbd>
    <kbd data-key="rshift"></kbd>
  </div>
  <div class="row">
    <kbd data-key="lctrl"></kbd>
    <kbd data-key="lwin"></kbd>
    <kbd data-key="lalt"></kbd>
    <kbd data-key="space"></kbd>
    <kbd data-key="ralt"></kbd>
    <kbd data-key="rwin"></kbd>
    <kbd data-key="rctx"></kbd>
    <kbd data-key="rctrl"></kbd>
  </div>  
</div>
<em>Press A Key</em>
body {
  display: flex; 
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  
  justify-content: center;
  align-items: center;  
  background-color: #111;
  background-image: 
    linear-gradient(45deg, fade-out(#222, 0.333), fade-out(#222, 0.666)),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/49914/grit-fs8.png);
  
  color: #999; 
  font-family: system-ui, sans-serif;
  
}

em { margin-top: 1rem; }

.keyboard {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-size: 0;
  border-radius: 4px;
  border: 13px solid #777;
  border-top-color: #666;
  border-bottom-color: #888;
  
  outline: 3px solid rgba(black, 0.2);
  outline-offset: -1px;
  box-shadow: 
    inset 0 1rem 1rem rgba(0,0,0, 0.5),
    0 2rem 3rem -0.5rem rgba(0,0,0,0.55);
  background-image: 
    radial-gradient(#111, #222);
  padding: 0.25rem;
}

$u1: 40px;

.row {
  height: $u1;
  display: flex;
  justify-content: space-between;
  width: $u1 * 15.43;
  padding-top: 1px;
  margin-bottom: 2px;
}

@mixin keycap($base: #e9e8e6) {
  $light: lighten($base, 2%); //#ece8e4
  $mid: darken($base, 16%); // #dedad6
  $dark: darken($base, 28%); // #c9c4c4
  background-color: $base;
  border-color: $mid;
  border-top-color: $light;
  border-bottom-color: $dark;
  box-shadow:
        0 -0.125em 0 -0.063em $dark,
        0 0.125em 0 -0.063em rgba(0,0,0,0.5);
  
  &::before {
    border-left-color: darken($base, 23%);
    border-right-color: darken($base, 23%);
    border-bottom-color: darken($base, 35%);
    box-shadow: 0 4px 4px -3px rgba(0,0,0,0.15);
    background-image:
            linear-gradient(
              to right,
              $base,
              desaturate(darken($base, 12%), 20%) 5%,
              transparent 40%,
              transparent 60%,
              desaturate(darken($base, 12%), 20%) 95%,
              $base
            );
  }
}

kbd {
  border-radius: 3px;
  box-sizing: border-box;
  color: rgba(0,0,0,0.75);
  display: inline-block;
  font-family: system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.125;
  padding: 0.33em 0.66em;
  position: relative;
  text-align: center;  
  vertical-align: middle;
  width: $u1; height: $u1;
  
  border: 3px solid transparent;
  border-top: 2px solid transparent;
  border-bottom: 6px solid transparent;
  
  &::before {
    content: '';
    position: absolute;
    top: 0px; left: -1px;
    bottom: -1px; right: -1px;
    border-radius: 4px;
    border-left: 1px solid transparent;
    border-right: 1px solid transparent;
    border-bottom: 1px solid transparent;
  }
  
  @include keycap();
  
  transition: transform 100ms;
  outline: 0;
  &:active, &.pressed {
    transform: 
      scale(0.96,0.96)
      translate(0, 3px);
  }
  
  &[data-key]::after {
    position: relative;
    z-index: 1;
    content: attr(data-key);
    text-transform: capitalize;
  }
  
  &[data-alt]::after {
    white-space: pre;
    content: attr(data-alt) '\A' attr(data-key);
    line-height: 0.95rem;
    font-size: 0.7em;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    text-align: center;
  }
  
  &[data-key=tab], 
  &[data-key=enter],
  &[data-key=caps],
  &[data-key=backspace],
  &[data-key=lshift],
  &[data-key=rshift],
  &[data-key=lctrl],
  &[data-key=rctrl],
  &[data-key=lalt],
  &[data-key=ralt],
  &[data-key=lwin],
  &[data-key=rwin],
  &[data-key=rctx] {    
    &:after {
      font-size: 0.725em; 
      top: 0;
      left: 0; right: 0;
      line-height: $u1 * 0.78;
      position: absolute;
    }
    @include keycap(#7f8384);
  }
  
  &[data-key=lshift], &[data-key=rshift] {
    &::after { content: 'Shift'; }
  }
  
  &[data-key=lctrl], &[data-key=rctrl] {
    &::after { content: 'Ctrl'; }
  }  
  
  &[data-key=lwin], &[data-key=rwin] {
    &::after { content: '\2756'; font-size: 1rem;  }
  }    
  
  &[data-key=lalt], &[data-key=ralt] {
    &::after { content: 'Alt'; }
  }      
  
  &[data-key=space]::after { content: none; }
  &[data-key=rctx]::after { content: '\2630'; }
  
  &[data-key=lalt], &[data-key=ralt] {
    &::after { content: 'Alt'; }
  }      
  
  &[data-key="tab"],
  &[data-key="\\\\"] {
    width: $u1 * 1.5;
  }
  
  &[data-key=caps] { width: $u1 * 1.75; }
  &[data-key=backspace] { width: $u1 * 2; }
  &[data-key=enter] { width: $u1 * 2.25; }  
  &[data-key=lshift] { width: $u1 * 2.25; }
  &[data-key=rshift] { width: $u1 * 2.75; }
  
  &[data-key=lctrl],
  &[data-key=rctrl],
  &[data-key=lalt],
  &[data-key=ralt],
  &[data-key=lwin],
  &[data-key=rwin],
  &[data-key=rctx] { width: $u1 * 1.25; }
  
  &[data-key=space] { width: $u1 * 6.25; }
}
View Compiled
// JS for interactive keyboard fun...
const $key = (key) => (
  document.querySelector(`kbd[data-key='${key}'], kbd[data-alt='${key}']`)
);

const codeToElement = {
  'CapsLock': $key('caps'),
  'Space': $key('space'),
  'Backslash': document.getElementById('backslash'),
  'Quote': document.getElementById('quote'),
  'ShiftLeft': $key('lshift'),
  'ShiftRight': $key('rshift'),
  'ControlLeft': $key('lctrl'),
  'ControlRight': $key('rctrl'),
  'AltLeft': $key('lalt'),
  'AltRight': $key('ralt'),
  'MetaLeft': $key('lwin'),
  'MetaRight': $key('rwin'),  
}

window.addEventListener('keydown', (e: Event) => {
  console.log(e);
  const el = codeToElement[e.code] || $key(e.key.toLowerCase());
  if (el) { 
    el.classList.add('pressed');
    e.preventDefault();
  } 
});

window.addEventListener('keyup', (e: Event) => {
  const el = codeToElement[e.code] || $key(e.key.toLowerCase());
  if (el) {  
    el.classList.remove('pressed'); 
    e.preventDefault();
  }
})
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.