JavaScript keyboard events help you capture user interactions with the keyboard.

Like many other JavaScript events, the KeyboardEvent interface provides all the required properties and methods for handling every keystroke a user makes using the keyboard.

There have been many articles written about how they work and how to use them. At the same time, W3.org keeps updating the specification by introducing new properties, deprecating existing ones, and marking certain code as legacy.

Because of this, it is essential for web developers to keep learning about the KeyboardEvent interface to know what exactly they should use and what's no longer relevant.

In this article, we will learn about:

  • The KeyboardEvent interface.
  • The keyboard event types we need to focus on.
  • The keyboard event types we may not ever need.
  • Which properties you need in practice and how different browsers handle them.
  • What is deprecated, and what's in use.
  • A playground to try things out as we learn.
  • Finally, the current list of key codes for reference and future use.

Hope you enjoy it.

The KeyboardEvent interface and the event types

The KeyboardEvent interface provides information using the defined constants, properties, and a single method (as of January 2021). It extends the UIEvent interface which eventually extends the Event interface.

Image KeyboardEvent Hierarchy

There are primarily three keyboard event types, keydown, keypress and, keyup. We can get contextual information about these events from the KeyboardEvent interface's properties and methods.

You can add each of these event types to an HTML element or document object using the addEventListener method. Here is an example of listening to a keydown event on an element whose id is, 'type-here':

let elem = document.getElementById('type-here');

elem.addEventListener("keydown", function (event) {
    // The parameter event is of the type KeyboardEvent
      addRow(event);
});

Alternatively, you can use the handler methods like, onKeydown(event), onKeyup(event), onKeypress(event) with the element to handle keyboard events. Here is an example of handling a keyup event on an input element:

<input type="text" id="type-here" onkeyup="doSomething(event)">

If you print the event object in the browser's console, you will see all its properties and methods along with the ones it inherits from the UIEvent and Event interfaces.

Image I have pressed the key, a while handling the keyup event

Try This Interactive Keyboard Event Playground

Before we go any further, how about a playground to explore all the keyboard events, their properties, characteristics, and so on? I think it will be awesome to use it alongside this article and beyond.

Just focus your cursor anywhere in the app embedded below, and type any key to see the contextual information about it.

You can also filter out the events you want by unchecking the checkboxes at the top. So give it a try:

If you have any issues in accessing the playground above, you can access this tool directly here: https://keyevents.netlify.app/

And you can find the source code of the demo from here: https://github.com/atapas/js-keyevents-demo

keydown, keypress, keyup - which one should you use?

The keyboard events are:

  • keydown: It fires when any key is pressed down.
  • keypress: It fires only when a key that produces a character value is pressed down. For example, if you press the key a, this event will fire as the key a produces a character value of 97. On the other hand, this event will not fire when you press the shift key as it doesn't produce a character value.
  • keyup: It fires when any key is released.

If all three events are attached to a DOM element, the firing order would be:

  1. First, keydown
  2. Next, keypress (with the condition stated above)
  3. Last, keyup

Among these events, the most used Keyboard event is (or, should be) keydown because:

  • The keydown event has the maximum coverage of keys to produce the contextual information. The keypress event works only for a subset of the keys. You can't capture the Alt, Ctrl, Shift, Meta, and other similar key events with a keypress. This also means that we can not fire the keypress event with key combinations like Ctrl Z, Shift Tab, and so on.
  • Moreover, the keypress event has been deprecated. This is a big enough reason to avoid it.
  • While both keydown and keyup events cover all the keys and are well supported by most browsers, there are a few differences that push keydown ahead of keyup. The keydown event fires before the browser processes the key, whereas the keyup event fires after the browser processes the key. If you cancel a keydown event (say, using event.preventDefault()), the browser's action will be canceled too. In case of the keyup event, the browser's action will not be canceled even when you have canceled the event.

In the example below, we are using event.preventDefault() when a keydown or keyup event fires. The bowser's action to write the key characters into the textbox will not be performed in the case of keydown but it will continue to happen for keyup.

With all that explanation, the keydown event is a clear winner and should become the most popular (used) key event type.

How to use the KeyboardEvent properties in practice

This is the billion dollar question! The shortest answer is, it depends. But on what? It depends on:

  • The browser support for your application
  • How legacy is your application code is and how much are you willing to refactor?

But before we get there, let's see a preview of some of the the useful properties and methods of the KeyboardEvent interface.

Proprty/MethodDescriptionDeprecated/Outdated
altKeyReturns a boolean(true/false). The value is true when Alt key is pressed.No
ctrlKeyReturns a boolean(true/false). The value is true when Control key is pressed.No
shiftKeyReturns a boolean(true/false). The value is true when Shift key is pressed.No
metaKeyReturns a boolean(true/false). The value is true when any of the Meta keys are pressed.No
codeCode value of the Physical Key.No
keyThe actual value of the key pressed.No
getModifierState() methodReturns a boolean(true/false). The value true indicates the on state of these keys, CapsLock, NumLock, Alt, Control, Shift, Meta, etc.No
charCodeReturns the Unicode value. This has been deprecated and we should use the key property instead.Yes
keyCodeReturns the neumeric code of the pressed value. This has been deprecated and we should use the key property instead.Yes
whichReturns the neumeric code of the pressed value. This has been deprecated and we should use the key property instead.Yes

The last three properties are deprecated and you should use the key property instead. The key property has the widest browser support.

It is supported on:

  • Microsoft Edge: Version >= 79
  • Firefox: Version >= 29
  • Google Chrome: Version >= 51
  • Safari: Version >= 10.1

So as long as you are not using any of the older browsers, the event.key property should be enough for you to identify a key. In case you have to support an older browser, a better fallback would be the event.which property.

window.addEventListener("keydown", function (event) {

  if (event.key !== undefined) {
    // Handle the event with KeyboardEvent.key
  } else if (event.which !== undefined) {
    // Handle the event with KeyboardEvent.which
  }
});

If your code uses any of the deprecated properties and you have an opportunity to refactor that code, it is always better to go for it.

Modifier Keys

The modifier keys are the special keys on your keyboard that modify the default behavior of the other keys. Control, Shift, and Alt are some modifier keys. When a modifier key is combined with another key, you can expect a different action to occur.

For example, if you press the key z, it is supposed to return the key and code for the letter z. If you combine it with the modifier Control and press Control z, you will likely get an Undo operation. Let's see it with some more examples in the next section.

The properties, event.altKey, event.ctrlKey, event.shiftKey, and so on help detect if a modifier key has been pressed.

Key Combinations

We can combine multiple keys and perform actions based on the key combinations. The code snippet below shows how to combine the Control and z key to define an action:

document
  .getElementById("to_focus")
  .addEventListener("keydown", function(event) {
    if (event.ctrlKey && event.key === "z") {
      // Do Something, may be an 'Undo' operation
    }
});

Here is another example that demos a few more key combinations. Please give it a try:

A Full List of Key Event Values

The table below shows a list of keys with the event.which, event.key and event.code values.

Key Nameevent.whichevent.keyevent.codeNotes
backspace8BackspaceBackspace
tab9TabTab
enter13EnterEnter
shift(left)16ShiftShiftLeftevent.shiftKey is true
shift(right)16ShiftShiftRightevent.shiftKey is true
ctrl(left)17ControlControlLeftevent.ctrlKey is true
ctrl(right)17ControlControlRightevent.ctrlKey is true
alt(left)18AltAltLeftevent.altKey is true
alt(right)18AltAltRightevent.altKey is true
pause/break19PausePause
caps lock20CapsLockCapsLock
escape27EscapeEscape
space32SpaceThe event.key value is a single space.
page up33PageUpPageUp
page down34PageDownPageDown
end35EndEnd
home36HomeHome
left arrow37ArrowLeftArrowLeft
up arrow38ArrowUpArrowUp
right arrow39ArrowRightArrowRight
down arrow40ArrowDownArrowDown
print screen44PrintScreenPrintScreen
insert45InsertInsert
delete46DeleteDelete
0480Digit0
1491Digit1
2502Digit2
3513Digit3
4524Digit4
5535Digit5
6546Digit6
7557Digit7
8568Digit8
9579Digit9
a65aKeyA
b66bKeyB
c67cKeyC
d68dKeyD
e69eKeyE
f70fKeyF
g71gKeyG
h72hKeyH
i73iKeyI
j74jKeyJ
k75kKeyK
l76lKeyL
m77mKeyM
n78nKeyN
o79oKeyO
p80pKeyP
q81qKeyQ
r82rKeyR
s83sKeyS
t84tKeyT
u85uKeyU
v86vKeyV
w87wKeyW
x88xKeyX
y89yKeyY
z90zKeyZ
left window key91MetaMetaLeftevent.metaKey is true
right window key92MetaMetaRightevent.metaKey is true
select key (Context Menu)93ContextMenuContextMenu
numpad 0960Numpad0
numpad 1971Numpad1
numpad 2982Numpad2
numpad 3993Numpad3
numpad 41004Numpad4
numpad 51015Numpad5
numpad 61026Numpad6
numpad 71037Numpad7
numpad 81048Numpad8
numpad 91059Numpad9
multiply106*NumpadMultiply
add107+NumpadAdd
subtract109-NumpadSubtract
decimal point110.NumpadDecimal
divide111/NumpadDivide
f1112F1F1
f2113F2F2
f3114F3F3
f4115F4F4
f5116F5F5
f6117F6F6
f7118F7F7
f8119F8F8
f9120F9F9
f10121F10F10
f11122F11F11
f12123F12F12
num lock144NumLockNumLock
scroll lock145ScrollLockScrollLock
audio volume mute173AudioVolumeMute⚠️ The event.which value is 181 in Firefox. Also FF provides the code value as, VolumeMute
audio volume down174AudioVolumeDown⚠️ The event.which value is 182 in Firefox. Also FF provides the code value as, VolumeDown
audio volume up175AudioVolumeUp⚠️ The event.which value is 183 in Firefox. Also FF provides the code value as, VolumeUp
media player181LaunchMediaPlayer⚠️ The ️event.which value is 0(no value) in Firefox. Also FF provides the code value as, MediaSelect
launch application 1182LaunchApplication1⚠️ The ️event.which value is 0(no value) in Firefox. Also FF provides the code value as, LaunchApp1
launch application 2183LaunchApplication2⚠️ The ️event.which value is 0(no value) in Firefox. Also FF provides the code value as, LaunchApp2
semi-colon186;Semicolon⚠️ The event.which value is 59 in Firefox
equal sign187=Equal⚠️ The event.which value is 61 in Firefox
comma188,Comma
dash189-Minus⚠️ The event.which value is 173 in Firefox
period190.Period
forward slash191/Slash
Backquote/Grave accent192`Backquote
open bracket219[BracketLeft
back slash220\Backslash
close bracket221]BracketRight
single quote222'Quote

Please Note:

  • event.which has been deprecated(or outdated)
  • The event.code value is the same for small letters(a) and capital letters(A). Hoever the event.key value represents the actual letter.
  • The event.which value is different in Firefox(FF) and other browsers for the keys, equal(=), semicolon(;), and dash/minus(-)

How about the Virtual Keyboard?

So what about virtual keyboards, like using our mobile phones or tablets or any other input devices?

The specification says that if the virtual keyboard has a similar key layout and functionality to a standard keyboard, then it must result in an appropriate code attribute. Otherwise, it is not going to return the right value.

In Summary

To Summarize:

  • You can use the KeyboardEvent to capture user interactions using a Keyboard.
  • There are primarily three key events, keydown, keypress, and keyup.
  • We should use the keydown event type as much as possible as it satisfies most of the use-cases.
  • The keypress event type has been deprecated.
  • The event.which property has been deprecated. Use event.key wherever possible.
  • If you have to support an older browser, use appropriate fallback for key detection.
  • We can combine multiple keys and perform operations.
  • The virtual keyboard supports these events as long as the layout and functions are similar to the standard keyboard.

That's all for now. Thank you for reading this far! Let's connect. You can @ me on Twitter (@tapasadhikary) with comments or feel free to follow.

Image From https://giphy.com/