Virtual Keyboard
Hello Guys! Welcome to Coding Torque. In this blog, I'm going to explain to you how to make a Virtual Keyboard using HTML, CSS and JavaScript. You can use this effect on your website/portfolio to showcase any skills/features. This will be a step-by-step guide. Let's get started 🚀.
Let's go step by step:
Step 1: HTML Code
<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>
Step 2: CSS(SCSS) Code
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; }
}
Output Till Now
Step 3: JavaScript Code
// 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();
}
})
Final Output
Code Credits: @32bitkid
Written by: Piyush Patil
If you want me to code any project or post any specific post,
feel free to DM me at IG @code.scientist or @codingtorque
If you have any doubt or any project ideas feel free to
Contact Us
Hope you find this post helpful💖
Follow us on Instagram for more projects like
this👨💻