JavaScript Keycodes: A Complete Guide to Keyboard Event Handling
Learn how to handle keyboard events in JavaScript with the modern key and code properties, plus best practices for building responsive web applications.
Keyboard interactions are fundamental to creating responsive web applications, from form validation to keyboard shortcuts and interactive games. JavaScript provides a robust KeyboardEvent API that enables developers to capture and respond to user keystrokes with precision.
Understanding the differences between key, code, and the deprecated keyCode properties is essential for building applications that work consistently across different keyboard layouts and devices. This guide explores the modern approach to keyboard event handling, covering best practices that ensure your code remains performant, accessible, and future-proof.
Whether you're building web applications with intuitive keyboard shortcuts or creating interactive gaming experiences, mastering keyboard events is essential for delivering exceptional user experiences.
Understanding KeyboardEvent Properties
The JavaScript KeyboardEvent API has evolved significantly over the years. Modern browsers now provide clear, semantic properties for keyboard interaction that work consistently across different keyboard layouts and devices.
The key Property: Character-Based Detection
The KeyboardEvent.key property returns the value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
For example, pressing the 'a' key on a QWERTY keyboard will return 'a' normally, but 'A' when Shift is held down, and entirely different characters on alternative keyboard layouts. The key property handles these variations automatically, making it the preferred choice for most text-related keyboard interactions.
This property also supports special key values like 'Enter', 'Escape', 'Tab', 'ArrowUp', and many others defined in the UI Events specification. Using key ensures your code works correctly regardless of the user's keyboard language setting or capitalization preferences.
1document.addEventListener('keydown', (event) => {2 console.log(`Key pressed: ${event.key}`);3 4 // Check for specific characters5 if (event.key === 'Enter') {6 console.log('Enter key pressed');7 }8 9 // Shift-aware character detection10 if (event.key === 'A') {11 console.log('Uppercase A with Shift');12 }13 14 // Arrow key detection15 if (event.key.startsWith('Arrow')) {16 console.log(`Arrow key: ${event.key}`);17 }18});The code Property: Physical Key Identification
The KeyboardEvent.code property represents a physical key on the keyboard, as opposed to the character generated by pressing the key. This property returns a value that isn't altered by keyboard layout or the state of modifier keys.
This makes the code property particularly valuable for gaming applications where you want consistent control mapping regardless of the user's keyboard language setting. For instance, the WASD keys for movement will always return 'KeyW', 'KeyA', 'KeyS', and 'KeyD' respectively, even on AZERTY keyboards where those physical positions produce different characters.
The code property uses string identifiers like 'KeyA', 'Digit1', 'ArrowLeft', 'Enter', 'Space', and 'Tab' that describe the physical location of the key rather than its current character output. This provides reliable, consistent key detection for gaming and keyboard shortcuts that should work identically across all keyboard layouts.
1// WASD game controls - works on any keyboard layout2document.addEventListener('keydown', (event) => {3 switch (event.code) {4 case 'KeyW':5 moveForward();6 break;7 case 'KeyA':8 moveLeft();9 break;10 case 'KeyS':11 moveBackward();12 break;13 case 'KeyD':14 moveRight();15 break;16 case 'Space':17 jump();18 break;19 }20});The Deprecated keyCode and which Properties
The KeyboardEvent.keyCode property was a legacy numeric code representing a system and implementation dependent value identifying the unmodified value of the pressed key. This property has been deprecated and should no longer be used in new projects.
Similarly, the event.which property provided cross-browser normalization but is also considered obsolete. Modern applications should migrate to using key and code instead.
Legacy keyCode Reference Table:
| Key | Code | Key | Code | Key | Code |
|---|---|---|---|---|---|
| Backspace | 8 | '0' | 48 | 'a' | 65 |
| Tab | 9 | '1' | 49 | 'b' | 66 |
| Enter | 13 | '2' | 50 | 'c' | 67 |
| Shift | 16 | '3' | 51 | 'd' | 68 |
| Ctrl | 17 | '4' | 52 | 'e' | 69 |
| Alt | 18 | '5' | 53 | 'f' | 70 |
| Escape | 27 | '8' | 56 | 'i' | 73 |
| Space | 32 | '9' | 57 | 'n' | 78 |
| Left Arrow | 37 | 'p' | 80 | 's' | 83 |
| Up Arrow | 38 | 'q' | 81 | 'x' | 88 |
| Right Arrow | 39 | 'r' | 82 | 'z' | 90 |
| Down Arrow | 40 |
Note: Some keycodes differ between browsers, particularly on Firefox.
Keyboard Event Types
JavaScript provides three main keyboard event types, each serving different purposes in keyboard interaction handling.
keydown Event
The keydown event fires when a key is pressed down, and it fires repeatedly if the key is held down (depending on the operating system's key repeat settings). This event fires for all keys, including function keys, modifier keys, and special keys.
The keydown event is typically used for keyboard shortcuts, game controls, and any scenario where you need to detect the initial key press regardless of whether it produces a character. When handling keydown, you can call event.preventDefault() to block default browser behavior for certain keys.
Key considerations:
- Fires immediately when any key is pressed
- Repeats during key hold (use
!event.repeatto detect initial press only) - Can prevent default browser behavior for most keys
- Fires for all keys including modifiers
1document.addEventListener('keydown', (event) => {2 // Only handle initial key press, not repeat3 if (event.repeat) {4 return;5 }6 7 // Prevent default for certain shortcuts8 if (event.ctrlKey && event.key === 's') {9 event.preventDefault();10 saveDocument();11 }12 13 console.log(`Key down: ${event.key}`);14});keyup Event
The keyup event fires when a key is released, providing a clean signal for when a key action is complete. This event does not repeat during key hold, making it ideal for toggle actions or state management.
Common use cases:
- Releasing drag operations
- Ending text selection with Shift+Arrow keys
- Implementing keyboard shortcuts that should only trigger on key release
- Tracking key state for multi-key combinations
Using keyup for completion actions often provides a better user experience than keydown alone, as it confirms the user intentionally completed the key press.
1// Track key release for drag operations2const keysPressed = new Set();3 4document.addEventListener('keydown', (event) => {5 keysPressed.add(event.code);6});7 8document.addEventListener('keyup', (event) => {9 keysPressed.delete(event.code);10 11 // Check if all WASD keys are released12 if (!keysPressed.has('KeyW') && 13 !keysPressed.has('KeyA') && 14 !keysPressed.has('KeyS') && 15 !keysPressed.has('KeyD')) {16 stopPlayerMovement();17 }18});keypress Event (Deprecated)
The keypress event fired when a key that produces a character value was pressed, making it useful for text input scenarios. However, this event has been deprecated and should not be used in new code.
Migration from keypress:
- For character detection: use
keydownwithevent.keychecking - For text input: use the
inputevent for real-time value changes - For form handling: rely on change and submit events
Avoid keypress in new development to ensure your code remains compatible with future browser versions.
Handling Modifier Keys
Modern JavaScript provides boolean properties on keyboard events that indicate the state of modifier keys, enabling complex keyboard shortcut handling without requiring separate key tracking logic.
Modifier Key Properties
The following boolean properties are available on all keyboard events:
event.shiftKey- True if Shift was held during the key pressevent.ctrlKey- True if Ctrl was held during the key pressevent.altKey- True if Alt (Option) was held during the key pressevent.metaKey- True if Meta (Command on Mac, Windows key on Windows) was held
These properties enable complex keyboard shortcut handling without requiring separate key tracking logic. For example, detecting Ctrl+S for a save action involves checking both the key code and the modifier state simultaneously.
1document.addEventListener('keydown', (event) => {2 // Ctrl+S to save3 if (event.ctrlKey && event.key === 's') {4 event.preventDefault();5 saveDocument();6 }7 8 // Ctrl+Shift+P for print preview9 if (event.ctrlKey && event.shiftKey && event.key === 'p') {10 event.preventDefault();11 openPrintPreview();12 }13 14 // Escape to close modal15 if (event.key === 'Escape') {16 closeModal();17 }18 19 // Alt+Arrow for special navigation20 if (event.altKey && event.key.startsWith('Arrow')) {21 handleAltNavigation(event.key);22 }23});Best Practices for Keyboard Event Handling
Following these best practices ensures your keyboard interactions are performant, accessible, and cross-browser compatible.
Performance Optimization
Keyboard event handlers should be lightweight and efficient, as they can fire hundreds of times per second during key repeats.
Optimization strategies:
- Keep handlers lightweight and avoid DOM manipulation
- Use event handlers to update state or set flags
- Perform expensive operations asynchronously
- Use
requestAnimationFramefor visual updates - Debounce rapid keyboard inputs for search operations
- Check
event.repeatto ignore repeated key holds
Example debounce pattern:
let searchTimeout;
document.addEventListener('keydown', (event) => {
if (event.target.tagName === 'INPUT') return;
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
performSearch(event.key);
}, 300);
});
Accessibility Considerations
Keyboard accessibility is essential for users who cannot use pointing devices. Ensuring your keyboard interactions are accessible benefits all users.
Essential accessibility practices:
- Visible focus indicators - Never remove focus outlines without providing alternatives
- Logical tab order - Ensure interactive elements are reachable via keyboard
- Don't trap focus - Custom interactions should not prevent navigation away
- Avoid interfering with browser shortcuts - Don't override common shortcuts
- Provide feedback - Users should receive clear feedback when actions trigger
- Test with screen readers - Ensure compatibility with assistive technology
ARIA attributes and proper semantic HTML provide the foundation for accessible keyboard interactions in web development.
Cross-Browser Compatibility
While modern browsers have converged on the key and code properties, some edge cases may still require consideration.
Browser consistency notes:
- The deprecated
keyCodeproperty had inconsistent implementations across browsers - Some special keys like the Command key on Mac may behave differently
- Always test on multiple browsers and devices
Testing requirements:
- Desktop browsers (Chrome, Firefox, Safari, Edge)
- Mobile keyboards and virtual keyboards
- Assistive technology input methods
- Different keyboard layouts (QWERTY, AZERTY, Dvorak)
Feature detection pattern:
const useModernKeyAPI = 'key' in KeyboardEvent.prototype;
The key and code properties are well-supported in all modern browsers, making them safe choices for new development.
Common Use Cases
Keyboard events enable a wide range of interactive features in modern web applications.
Form Input Validation
Keyboard events enable real-time input validation and formatting as users type.
Common applications:
- Phone number formatting with automatic spacing
- Credit card spacing every 4 digits
- Uppercase conversion for specific fields
- Numeric-only input restriction
document.getElementById('phone').addEventListener('keydown', (e) => {
// Allow control keys
if (e.ctrlKey || e.altKey || e.metaKey) return;
// Allow only numbers, backspace, delete, arrows
if (!/\d/.test(e.key) && !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
e.preventDefault();
}
});
Note: For input value formatting, the input event is often more reliable than keyboard events alone, as it catches pastes and other input methods.
Game Controls
Games often use the code property for consistent control mapping across different keyboard layouts.
WASD movement example:
const keys = {
KeyW: false,
KeyA: false,
KeyS: false,
KeyD: false
};
document.addEventListener('keydown', (e) => {
if (e.code in keys) {
keys[e.code] = true;
updatePlayerMovement();
}
});
document.addEventListener('keyup', (e) => {
if (e.code in keys) {
keys[e.code] = false;
updatePlayerMovement();
}
});
function updatePlayerMovement() {
const dx = (keys.KeyD ? 1 : 0) - (keys.KeyA ? 1 : 0);
const dy = (keys.KeyS ? 1 : 0) - (keys.KeyW ? 1 : 0);
movePlayer(dx, dy);
}
Using code values like 'KeyW' ensures the game responds to physical key positions regardless of keyboard layout.
Application Keyboard Shortcuts
Application-wide keyboard shortcuts benefit from attaching event listeners to the document or body, allowing shortcuts to work regardless of the currently focused element.
Best practices for application shortcuts:
- Attach listeners to
documentfor global shortcuts - Use
data-*attributes on elements to define shortcut keys - Provide visual feedback when shortcuts are active
- Allow users to customize or disable shortcuts
- Document all available shortcuts in your application
Conflict avoidance:
- Avoid common browser shortcuts (Ctrl+T, Ctrl+W, Ctrl+N, F5, F11)
- Be careful with Ctrl+Tab, Ctrl+F4, Ctrl+P
- Consider using Ctrl+Shift or Ctrl+Alt for custom shortcuts
- Check for active element before triggering shortcuts in forms
Properly implemented keyboard shortcuts significantly enhance power user productivity and application usability, making your web applications more efficient and professional.
Conclusion
JavaScript keyboard event handling has evolved significantly, with the key and code properties providing clear semantics for character-based and physical key detection respectively. The deprecated keyCode and which properties should be avoided in new development.
Key takeaways:
- Use
keyfor character-based detection in text input and character-level interactions - Use
codefor physical key detection in gaming and layout-independent controls - Prefer
keydownandkeyupover the deprecatedkeypressevent - Keep handlers lightweight and use debouncing for expensive operations
- Ensure accessibility with proper focus management and visible indicators
- Test across browsers and devices to ensure consistent behavior
By following these best practices, you can create robust keyboard interactions that enhance user experience while maintaining code quality and future compatibility. Our web development services team specializes in building interactive web applications with thoughtful keyboard handling and full accessibility compliance.
Frequently Asked Questions
What is the difference between event.key and event.code?
event.key returns the character value produced by the key press, considering modifier keys and keyboard layout. event.code returns the physical key location on the keyboard, which remains consistent regardless of layout. Use key for text input, code for gaming controls.
Should I still use keyCode in 2025?
No. keyCode has been deprecated and should not be used in new projects. Modern browsers support event.key and event.code, which provide better semantic meaning and cross-browser consistency.
How do I prevent keyboard events from triggering browser shortcuts?
Call event.preventDefault() in your keydown event handler. Be careful not to interfere with essential browser shortcuts like F5 (refresh) or Ctrl+W (close tab) unless you have a good reason.
How do I detect if a key is being held down?
Use the event.repeat property in your keydown handler. It returns true for repeated events during key hold, allowing you to handle only the initial key press if needed.
What keyboard events work on mobile devices?
Mobile browsers have limited keyboard event support. Virtual keyboards typically don't fire keyboard events in the same way as physical keyboards. Consider using input events or touch events for mobile-specific interactions.