Sessions is temporarily moving to YouTube, check out all our new videos here.

Keyboard Controls for an International User Base

Manuel Matuzović speaking at viennaJS in May, 2017
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

The UI Events specification comes with two new properties for keyboard events: key and code. They replace the previously existing (and still existing) charCode, keyCode, and which. It’s not just easier to work with keyboard events but it also improves accessibility significantly. Manuel will introduce the new API and illustrate why and how it’s important to an international user base.


- First of all thank you everyone for having me and thank you all for coming. My name is Manuel Matuzovic and I'm a front end developer from Vienna. I'm born in Austria but my last name isn't a typical Austrian name as you can see, even though some of you may argue that a name ending in ic or vic is a very Viennese name but that's a whole other different story. It's not an Austrian name. It's a Bosnian name or actually now it's a Bosnian name because out of laziness I tend to ditch the critical sign, the accent aigu there because this one is a tze, and this one is a ch. In the Bosnian, Croatian and Serbian language there are some letters that don't exist in the English or German language, for example, ch and ch. They're different. If you ask my brother-in-law he will tell you but of course there's a different. One is ch and the other is ch. Ch, ch there's a different. Yeah, there is a difference but okay. And sher, zer and some other letters and we also don't have some letters like W, Q or X. So, we just don't have those letters in our writing system and our language. Of course, if there are differences in the alphabet we also have a different keyboard layout. A keyboard layout is an arrangement of legends, keys, key meaning, associations on a keyboard. For example, the QWERTY, I've no idea how to pronounce any of those so don't quote me on the names of the keyboard layouts. I'm just going to pronounce it the way I like it and I'm going to go with it so please don't quote me on that. So, the QWERTY layout. The name derives from the first six letters in the first alphabetical row, Q, W, E, R, T, and Y. It's mostly used in English-speaking countries. I guess most of you are familiar with this keyboard layout but it's also used in other languages as well. Then there is the QWERTZ, QWERTZ, whatever. It's used in German-speaking countries. One of the big differences compared to the QWERTY layout is that the letters Z and Y are switched, and of course we have umlauts and some of the special characters are in different locations. Then there's also the AZERTY keyboard layout. I didn't know about that one before I started to prepare for this talk. It's mostly used in French-speaking countries in Europe. So, France and Belgium and there are some regional differences between those countries, so there are also a lot of variations of keyboard layouts. There's a lot of stuff going on here. As you can see the Y is on the same position as on the QWERTY layout but the Z is in the first row instead of in the third row. The M, which is usually in the third row of alphabetical keys is in the second. The W is in the last one and the A is in the first one. So, there are a lot of differences. And of course there also keyboard layouts for other writing systems like for example, here in Russian, for the Russian language and for the Cyrillic letters. So, why am I talking about keyboard layouts and about strange sounding languages? Well, because if there are different keyboard layouts, that must at some point, somehow affect us as front end developers, and it does. And I'm going to show you how but before I do that, I want to show you what we have right now, what we can do with the keyboard or some of the stuff we can do. First of all, let's have a look at events. We have some events, for example, the keydown event which is fired when the user presses a key. Then there is the keyup event which is fired when the user releases a key. Pretty straightforward. Those are keyboard events, and then there's the keypress event which is fired when a key is pressed down but that just fires when a character key is pressed. Alright. Then we have some values. We have keyCode which returns a numerical code identifying the value of the pressed key and we also have which which is pretty much the same as keyCode in most modern browsers, and we have charCode which also returns a numerical code but especially for character keys. And it only returns a value in the keypress event, so for those special characters, for those character keys. As far as I know, charCode will return zero in a keydown or keyup event. This is just a simple example of a keydown event listener. Here checking if the keyCode's property in the event has a certain value, for example, 68 is the code for the letter D, so if the letter D is pressed, then whatever happens and here I'm checking for the code 90 which is the number for Z or Y, I'm not quite sure now and it does something else, okay? The thing is it works kind of but there are some issues. First of all, properties have different meanings within different events. For example, keyCode will return a different value in a keydown event than it does in a keypress event. So, the same key will return a different value, a different number. Let's say the Z key returns 90 in a keydown event but it will return 120, for example, in a keypress event. That can get quite confusing. Then values of keys in keypress events are different between browsers. So, it's possible that the keyCode property in a keypress event in Firefox will return a different value than it does in Chrome, for example. So, there are some cross browser issues and in general there are a lot of cross browser issues actually in all of those events and values. And keyCode tries to be kind of internationally friendly but it actually isn't, and I'm going to show you how this not being international friendly looks like. I have developed an incredibly awesome space shooter kind of game, you know. It's in an early alpha stage, so the transitions aren't very smooth and it only has basic functionality, so you can only control the ship and move it with the W, A, S and D keys, and you can shoot with the Y key, and that's how it looks like on a QWERTZ layout. You can see the keys pressed here. Great. Now if I switch to a QWERTY layout I can still move the ship using the W, A, S and D letters but if I press the Z key on my QWERTZ layout, nothing happens, and what you probably can't see because, yeah, it just doesn't work out of the beamer here, that the Y key is being locked, even though I'm pressing the Z key on my QWERTZ layout. That is happening because in the keydown event what we are actually listening to is not the physical key on the keyboard but what's printed on that key. So, if we switch keyboard layouts, if I press Z, Z doesn't register a Z key, the key in the first row but the letter Z, okay? In the QWERTZ layout the Z is in the first row of alphabetical letters, and in the QWERTY layout it's in the third row. So, I would have to press the Y key on my keyboard, on my QWERTZ keyboard in order to make the game work, so, this will be the keys I would have to use to control the ship and shoot. Which is okay. I can play it like that. It will work. I can still navigate pretty easy and I can shoot. It's not as comfortable as with a QWERTZ layout but it will work. Remember AZERTY? There's no way of playing that game with a French keyboard layout because as you can see S and D are on the same location but W which is moving forward is below S and D, A is on the top row and it just wouldn't work like that. And this is where the updated UI events pack comes into play and the key event API. It gives us two new properties or relative new properties, key and code. Key returns a printable character or a descriptive string. So, if I press K for example it will return K, if I press O, it will return O, if I press enter, it will return enter. And then we have the code property which returns a physical key or a code for a physical key. So, for example, if I press Y on a QWERTY layout, it will return key Y. If I press Z on a QWERTZ layout, what do you think it will return? - [Man] Key Y. - Key Y because it's on the same location. It's not about the letter that's printed on the letter but the actual physical letter on the keyboard. Of course, if there are codes for every letter, there must be some kind of reference keyboard and there is one provided by the W Free C in the specification and this is an image I took of the specification, and you can see every code for every key on whatever layout. Of course, there's much more to that. There are much more examples because if there are many keyboard layouts, things can get pretty tricky when you try to normalise them and make a standard. So, if we update the example I showed you before, we still have the keydown event, we still checking for stuff but in that case we don't check anymore for the keyCode property but just for code, and we are asking is a keypress that is identified by key Y, then should the missile do whatever we want? And now I'm switching to the US keyboard immediately but I'm still pressing the same letters and I'm still pressing W, S and D and Z on my QWERTZ layout and it just works, and even if I switch to the French keyboard layout, it works because like I said before we're not listening to the letters but to the actual physical keys on the keyboard layout which is great because now pretty much everyone can play our game and not just people with a specific keyboard layout. The browser support is pretty good. For the key property it works in all major browsers. In IE and Edge there are some issues. It's implemented but yeah, it doesn't work as it should, and the code property works also in most major browsers but not in IE or Edge. But that's not that big of a deal because we can provide a fallback. We can first check for the code property, so we can say if the letter D is pressed then move the ship to the right and we can provide an alternative to the W, A, S and D navigation just to make sure that everyone can use the game because the arrow keys are usually at the same position on every keyboard layout or at least on most keyboard layouts. So, that's an alternative and in the third row we are checking for the keyCode, so if the browser does not understand code or key, we can fall back to keyCode which works in every browser. Yeah, some notes. Some notes. Currently there's no way of checking which keyboard layout is currently being used by the user. So, I can't check if the user is using the QWERTY or the AZERTY or whatever keyboard layout, which would be great because if I know that the user is using the French keyboard layout I can provide them with specific instructions for the game just for that keyboard layout, for example but that doesn't work now and I'm not sure if there are plans for that. There is a property called repeat in the keydown and keyup event which provides us with a Boolean value which tells us if the key is being pressed continuously, so the first time repeat will return false and then every other time if the key is being pressed will return true, so that's a good way of checking if the user keeps pressing the key. You don't have to do anything else, we just check that property. And there also some other properties, the altKey, controlKey, metaKey and shiftKey which also return Boolean properties in order to make it possible for us to check if besides one character key, for example, a modifier key is pressed, so I can easily check if the user, for example, presses the K key and also the command key or also the control key. This is an, yeah, we're in noisy example but here you can see that I'm checking, I've pressed the letter K, and for the key property I get back K and for the metaKey property I get back true because I also pressed the command key while I pressed K. This is just something I put on CodePen so you can look at it and test all the properties we have and compare them between browsers and so on. So, the whole point of this is that the web is international and our users are very international, and we shouldn't assume that our users are using a certain device in a certain way and we also shouldn't assume that they're using a certain keyboard layout or a certain input device in general. So, if we use those properties, code and key instead of keyCode, we can make games or make apps or shortcuts for web apps for example that will work for whatever keyboard layout is being used by our users which is great, not just for accessibility but also for user experience. That's it.