Home - Mottie/Keyboard GitHub Wiki
<title>Virtual Keyboard with Special Keys</title>
<style>
body {
font-family: calibri;
padding: 1px solid;
}
.keyboard {
display: inline-block;
border: 3px solid green;background-color:yellow;
padding: 3px;
border-radius: 5px;
max-width: 400px;
}
.keys {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-bottom: 5px;
justify-content: center;
}
button.key, button.specialKey {
font-size: 1rem;color:white;
padding: 1px 1px;
cursor: pointer;
border: 1px solid blue ;
border-radius: 5px;
background-color: tomato;
user-select: none;
width: 28.7px;height:28px;
text-align: center;
}
button.key:focus, button.specialKey:focus {
outline: 1px solid purple;background-color:blue;
}
button.specialKey {
width: auto;
min-width: 60px;
font-weight: bold;
background-color:brown;
}
.controls {
display: flex;
gap: 5px;
justify-content: center;
margin-bottom: 10px;
}
button.control {
padding: 5px 5px;
border-radius: 5px;
border: 1px solid blue;
background-color: red;color:white;
cursor: pointer;
user-select: none;
font-weight: bold;
}
button.control.active {
background-color: blue;
color: white;
border-color: #0056b3;
}
button#shiftKey.active {
background-color:blue;
}
#output {
width: 346px;
min-height: 346px;
margin-bottom: 0px;
font-size: 1rem;
padding: 1px;
<script>
const output = document.getElementById('output');
const keyGroup = document.getElementById('keyGroup');
const shiftKey = document.getElementById('shiftKey');
const numbersKey = document.getElementById('numbersKey');
const abcKey = document.getElementById('abcKey');
const symbolsKey = document.getElementById('symbolsKey');
const clearKey = document.getElementById('clearKey');
const spaceKey = document.getElementById('spaceKey');
const backspaceKey = document.getElementById('backspaceKey');
const enterKey = document.getElementById('enterKey');
// Data for keys in each group with shifted variants
const keysData = {
numbers: {
normal: ['1','2','3','4','5','6','7','8','9','0'],
shifted: ['!','@','#','$','%','^','&','*','(',')']
},
abc: {
normal: 'abcdefghijklmnopqrstuvwxyz'.split(''),
shifted: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
},
symbols: {
normal: ['-', '/', ':', ';', '(', ')', '$', '&', '@', '"'],
shifted: ['_', '?', '+', '*', '[', ']', '{', '}', '\\', '|']
}
};
// Current state
let currentGroup = 'numbers';
let isShiftActive = false;
// Helper to update group button active states and aria-pressed
function updateGroupButtons() {
[numbersKey, abcKey, symbolsKey].forEach(btn => {
const isActive = (btn.id.startsWith(currentGroup));
btn.classList.toggle('active', isActive);
btn.setAttribute('aria-pressed', isActive);
});
}
// Render keys for current group and shift state
function renderKeys() {
keyGroup.innerHTML = '';
const keys = isShiftActive ? keysData[currentGroup].shifted : keysData[currentGroup].normal;
keys.forEach(key => {
const btn = document.createElement('button');
btn.className = 'key';
btn.type = 'button';
btn.textContent = key;
btn.setAttribute('aria-label', `Key ${key}`);
btn.addEventListener('click', () => {
output.value += key;
});
keyGroup.appendChild(btn);
});
}
// Toggle shift
shiftKey.addEventListener('click', () => {
isShiftActive = !isShiftActive;
shiftKey.setAttribute('aria-pressed', isShiftActive);
shiftKey.classList.toggle('active', isShiftActive);
renderKeys();
});
// Switch to Numbers group
numbersKey.addEventListener('click', () => {
currentGroup = 'numbers';
isShiftActive = false;
shiftKey.setAttribute('aria-pressed', false);
shiftKey.classList.remove('active');
updateGroupButtons();
renderKeys();
});
// Switch to ABC group
abcKey.addEventListener('click', () => {
currentGroup = 'abc';
isShiftActive = false;
shiftKey.setAttribute('aria-pressed', false);
shiftKey.classList.remove('active');
updateGroupButtons();
renderKeys();
});
// Switch to Symbols group
symbolsKey.addEventListener('click', () => {
currentGroup = 'symbols';
isShiftActive = false;
shiftKey.setAttribute('aria-pressed', false);
shiftKey.classList.remove('active');
updateGroupButtons();
renderKeys();
});
// Special keys functionality
clearKey.addEventListener('click', () => {
output.value = '';
});
spaceKey.addEventListener('click', () => {
output.value += ' ';
});
backspaceKey.addEventListener('click', () => {
output.value = output.value.slice(0, -1);
});
enterKey.addEventListener('click', () => {
output.value += '\n';
});
// Initialize
updateGroupButtons();
renderKeys();
</script>
border-radius: 5px;
white-space: pre-wrap;
background-color: white;
} </style>
SHIFT
123
ABC
#@!
Clear
Space
Backspace
Enter