![Jeff Posnick](https://web.dev/images/authors/jeffposnick.jpg) Jeff Posnick [X](https://twitter.com/jeffposnick) [GitHub](https://github.com/jeffposnick) [Homepage](https://jeffy.info/)

<br />

The past few versions of Chrome have seen two additions to [`KeyboardEvent`s](https://developer.mozilla.org/docs/Web/API/KeyboardEvent), which are used as a parameter passed to [`keydown`](https://developer.mozilla.org/docs/Web/Events/keydown), [`keypress`](https://developer.mozilla.org/docs/Web/Events/keypress), and [`keyup`](https://developer.mozilla.org/docs/Web/Events/keyup) event listeners. Both the [`code`](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/code) attribute (added in [Chrome 48](https://www.chromestatus.com/feature/5228092293382144)) and the [`key`](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/key) attribute (added in [Chrome 51](https://www.chromestatus.com/feature/4748790720364544)) give developers a straightforward way to get information that would otherwise be [difficult](https://github.com/inexorabletash/polyfill/blob/master/keyboard.md#legacy-key-events) using legacy attributes.

## The code attribute

First up is the `code` attribute. This is set to a [string](https://w3c.github.io/uievents-code/#code-value-tables) representing the key that was pressed to generate the `KeyboardEvent`, *without* taking the current keyboard layout (for example, [QWERTY](https://en.wikipedia.org/wiki/QWERTY) vs. [Dvorak](https://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard)), locale (for example, English vs. French), or any modifier keys into account.
This is useful when you care about which *physical* key was pressed, rather than which character it corresponds to. For example, if you're a writing a game, you might want a certain set of keys to move the player in different directions, and that mapping should ideally be independent of keyboard layout.

## The key attribute

Next, we have the new `key` attribute. It's also set to a [string](https://w3c.github.io/uievents-key/), but while `code` returns information about the physical key that was pressed, `key` contains the character that is generated by that key, taking into account the current keyboard layout, locale and modifier keys.
Looking at the `key` attribute's value comes in handy when you need to know what character would be displayed on the screen as if the user had typed into a text input.

## What's this mean in practice?

To give a concrete example, let's assume your user is using a U.S. keyboard with a QWERTY keyboard layout. Pressing the physical `Q` key on that keyboard will result in a `KeyboardEvent` with a `code` attribute set to `"KeyQ"`. This is true regardless of keyboard layout, and regardless of any other modifier keys. For comparison, on a French ([AZERTY](https://en.wikipedia.org/wiki/AZERTY)) keyboard this key would still have a `code` of `"KeyQ"` even though the letter printed on the keycap is an "a".
Pressing the physical `Q` key on that same U.S. keyboard will typically generate a `KeyboardEvent` with `key` set to `"q"` (with no modifier keys), or `"Q"` (with Shift or CapsLock), or `"œ"` (on OS X, with Alt). On a French AZERTY keyboard, this same key would generate an "a" (or "A" with Shift or CapsLock). And for other keyboard layouts, the `key` value could be `"й"`, `"ض"`, `"ㅂ"`, `"た"`, or some other character.
Revisiting our game example from earlier, if you want your game to use the WASD keys for movement, you can use the `code` attribute and check for `"KeyW"`, `"KeyA"`, `"KeyS"` and `"KeyD"`. This will work for all keyboards and all layouts---even AZERTY keyboards that swap the position of the "w" and "z" keys.

## Virtual keyboards

You'll notice that up until now, we've been focusing on the behavior assuming a physical keyboard. What about users who are typing on a virtual keyboard or an alternative input device? [The specification](https://w3c.github.io/uievents/#code-virtual-keyboards) offers official guidance for the `code` attribute. To summarize, a virtual keyboard that mimics the layout of a standard keyboard is expected to result in an appropriate `code` attribute being set, but virtual keyboards that adopt non-traditional layouts may result in `code` not being set at all.

Things are more straightforward for the `key` attribute, which you should expect to be set to a string based on which character the user (virtually) typed.

## Try it out

Gary Kačmarčík has put together a [fantastic demo](https://w3c.github.io/uievents/tools/key-event-viewer.html) for visualizing all the attributes associated with `KeyboardEvent`s:
![KeyboardEvent attributes](https://developer.chrome.com/static/blog/keyboardevent-keys-codes/image/keyboardevent-attributes-c629d096d39de.png)

## Cross-browser support

Support for the [`code`](http://caniuse.com/#feat=keyboardevent-code) attribute is, as of this writing, limited to Chrome 48+, Opera 35+, and Firefox 44+.
The [`key`](http://caniuse.com/#feat=keyboardevent-key) attribute is supported in Firefox 44+, Chrome 51+, and Opera 38+, with [partial support](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/key#Browser_compatibility) in Internet Explorer 9+ and Edge 13+.