DEV Community

loading...
Cover image for Boy, was it hard to implement proper keyboard shortcuts

Boy, was it hard to implement proper keyboard shortcuts

tillsanders profile image Till Sanders ・6 min read

I'm currently implementing a complete redesign of our primary administration interface. This web application is used by our customer service every day to read, write and process heaps of information and complex data structures. When you're designing an interface for such trained users, priorities shift a great deal. These users prefer speed over simplicity, so you start to seriously optimize things like navigation. And the easiest, maybe even the most important way to speed up navigation is by providing keyboard shortcuts. Most websites don't really use custom keyboard shortcuts because they take too much time to learn. But for users who spend many hours a day working with a web application, keyboard shortcuts are indispensable. And so my journey began...

TL;DR

I built a polyfill for the accessKeyLabel property that reveals the keyboard shortcut assigned by the browser and based on the accessKey property assigned to an interactive element. Browsers use different shortcuts for this and the accessKeyLabel property is the best way to improve the discoverability of custom shortcuts in web applications. Native support is missing in Chrome, IE and Edge. My AccessKeyLabelPolyfill is bridging the gap with less than 1 KB. GitHub | Demo

Using the accesskey property to quickly add keyboard shortcuts

Since HTML 4, we've had the power to add custom keyboard shortcuts to our webpage using the accesskey property.

<button accesskey="d">Do crazy stuff</button>
Enter fullscreen mode Exit fullscreen mode

Simply by adding this property to a button, I've set up a keyboard shortcut. In most browsers, pressing Ctrl + Alt + D will now trigger this button. Great! So I just added this to a number of buttons in our application and called it a day? Unfortunately not. See, what modifier keys (Ctrl, Alt, Shift, etc.) will be combined to a shortcut is not standardized. And I wish that was the only problem.

Browsers don't use the same key to make the shortcuts

So, as I said, most browsers use Ctrl + Alt. At least on macOS. Except for Firefox before version 14. Back then, it only used Ctrl. On Windows, the same browsers generally use only the Alt key. Except for Firefox, which seems to strive for cross-platform consistency. Nice. These are, however, only the browsers whose behaviour was documented on MDN. As you know there are loads more. And at least some even allow to customise their behaviour. This means that the actual shortcut depends on the browser, it's version, your operating system and possibly your personal settings. But don't worry, it get's worse.

Users are unaware of keyboard shortcuts on websites

Let's face it. Most people are completely dumbfounded when it comes to keyboard shortcuts. If you're ever trying to impress people, just show them the Tab key. But when they're working with the same application every day, we should try to educate them to help speed things up. So now that we have keyboard shortcuts thanks to accesskey, how can we make them easily discoverable?

Proven technique to indicate keyboard shortcuts

For some reason, I'm seeing this technique less and less in modern systems – probably due to aesthetic reasons. But it has been around for decades and I doubt that it get's any more elegant than this. The idea is simple and every little as space-saving as it is helpful: just underline the character that is the access key.

<button accesskey="d"><u>D</u>o crazy stuff</button>
Enter fullscreen mode Exit fullscreen mode

By using a consistent scheme (like Ctrl+ Alt / Alt) and underlining the access key, we give users a subtle hint or reminder which character provides access to a specific action. Neat.

Underlining the access key is not enough

We surely can improve the discoverability of our shortcuts even more. Right now, the biggest issue is that users are probably unfamiliar with the default keyboard shortcut of their browser. So why don't we add a small reminder. For big buttons with enough space, we could add a small text below. For others, we could add tooltips or use the title attribute.

<button accesskey="d">Do crazy stuff</button>
<small>Hint: Use Ctrl + Alt + D to quickly access this button!</small>
Enter fullscreen mode Exit fullscreen mode

Great! But as we learned in the beginning, browsers use different modifier keys for our shortcuts. How do we handle this?

The accessKeyLabel API reveals the exact shortcut

Thankfully, the accessKeyLabel API of HTML 5 will tell us the exact keyboard shortcut the browser assigned to our button. That's great! We can access this property in a Vue.js component and add it to our hint easily. No magic required.

Chrome does not support accessKeyLabel

Well, I must admit – I didn't see that one coming. While accesskey is supported perfectly, Chrome, Internet Explorer (okay, no surprise...), Edge, Safari for iOS < v13 and more don't (yet) support accessKeyLabel. That's a bummer. Firefox and Safari for macOS however, have good support. But it's still not enough to rely on.

Use my polyfill

As it turns out, there is a ticket in the bug tracker of the chromium project that's been calling to add support for the accessKeyLabel property since 2014. Unfortunately, other things seem to have a higher priority, so until native support arrives in all major browser, we need a polyfill.

What is a polyfill?

A polyfill is a script that patches native functionality that has not yet arrived in certain browsers or will not arrive because of old age. Polyfills generally aim to provide the exact same functionality and API as the original specification. Some things, however, can only be partially implemented using polyfills. What's great about polyfills is that they allow us to use new technologies without needing to worry too much about "older" browsers. The disadvantage is, of course, that we're adding more code to our website that might slow it down a little bit more. That being said, most polyfills are actually quite small.

My search for a polyfill was surprisingly unsuccessful. I stumbled upon a jQuery plugin, but wanted something vanilla JavaScript.

Sometimes, to provide great user experience and accessibility, you have to go to great lengths. I tend to do that. So here is my very first polyfill. It is vanilla JavaScript and weighs under 1 KB:

GitHub logo tillsanders / access-key-label-polyfill

Polyfills the accessKeyLabel property to improve discoverability of native keyboard shortcuts for your website. Tiny and dependency-free.

AccessKeyLabelPolyfill

Polyfills the accessKeyLabel property to improve discoverability of native keyboard shortcuts for your website. Tiny (< 1KB) and dependency-free.

With the accesskey HTML property you can easily provide keyboard shortcuts for the buttons of your web application.

<button accesskey="D">Do crazy stuff</button>
<!-- Can be activated using Ctrl + Alt + D -->
Enter fullscreen mode Exit fullscreen mode

Sadly, most users don't even know these shortcuts can be used, even if the web developer provided them. To make these shortcuts more discoverable you might decide to use the title property, a tooltip or some other UI element to display the keyboard shortcut.

<button accesskey="D">Do crazy stuff</button>
<small>Hint: Use Ctrl + Alt + D to quickly access this button!</small>
Enter fullscreen mode Exit fullscreen mode

A good idea, but browsers use different combinations of modifier keys. But…

Installation and usage of the AccessKeyLabelPolyfill

You can install the polyfill using npm or yarn:

npm i access-key-label-polyfill
# or
yarn add access-key-label-polyfill
Enter fullscreen mode Exit fullscreen mode

And then import and execute like this:

import installAccessKeyLabelPolyfill from 'access-key-label-polyfill';
installAccessKeyLabelPolyfill();
Enter fullscreen mode Exit fullscreen mode

Reading the accessKeyLabel

I integrated this into a Vue.js button component that also has some neat methods to automatically underline the first occurrence of the accessKey in the button caption, but you might use it any way you like. You can read the documentation of the accessKeyLabel property on MDN, because the API of the polyfill is exactly the same. But it's quite simple, so here is an example:

const label = document.querySelector('#button').accessKeyLabel;
Enter fullscreen mode Exit fullscreen mode

The polyfill will first check if accessKeyLabel is supported natively and exit if so. Otherwise it will try to detect the browser and operating system and return the correct keyboard shortcut as a string that can be displayed in a <small> tag, a tooltip, or the title attribute. Get creative!

If you're using the polyfill with Vue.js, React, Svelte, Angular or other frameworks, remember to only load it once!

Try the demo!

You can visit the demo to try the plugin right in your browser. The demo will also tell you wether the polyfill detected native support or not. Try the demo!

The state of keyboard shortcuts in web applications

Today's odyssey into the accessKeyLabel property revealed to me the many issues we face regarding shortcuts in web applications. Not only are the shortcuts not standardised and support for the simple accessKeyLabel API is missing in most browsers, but I was unable to discover the shortcut in Chrome for Android. Maybe I was due to a lack of a proper Android tablet for testing or maybe accesskey is simply not supported. To me, it's unclear how access keys might interfere with screen readers, browser shortcuts or even other applications. There is also no standard on how browsers handle conflicting access keys. But what's easily the biggest issue is usage. It is rare to see a web application use these features, even the complex ones that would benefit greatly from it. By taking the time of writing and publishing this polyfill, I hope to make keyboard shortcuts in web applications more accessible to you all by bridging the gap in browser support.

Discussion (0)

pic
Editor guide