Keyboard shortcuts with Command and Control modifiers
When it comes to shortcuts, the Command key (Mac) and the Control key (Windows) are the same keys. This is because shortcuts that use the Command key on a Mac are activated with the Control key on Windows.
Here are some examples:
Shortcut |
Mac |
Windows |
Cut |
Command + x |
Control + x |
Copy |
Command + c |
Control + c |
Paste |
Command + v |
Control + v |
Undo |
Command + z |
Control + z |
So if you want to use the Command modifier for a keyboard shortcut, you need to make sure Windows users can active the same shortcut with Control.
To do this, you need to know whether the user is using Mac or Windows. The best way to tell is through the user agent. (This is the best way even though MDN recommends against using user agent).
const os = navigator.userAgent.includes('Mac OS X') !== -1
? 'mac'
: 'windows'
If the user uses a Mac, you get the Command key with event.metaKey
. If the user uses Windows, you get the Control key with event.ctrlKey
.
document.addEventListener('keydown', event => {
if (os === 'mac' && event.metaKey || os === 'windows' && event.ctrlKey) {
console.log('Command (Mac) or Control (Windows) Pressed!')
}
})
This condition (os === 'mac' ...
) can be quite long and difficult to read. We can chuck it into a function to make it more readable. I’m going to call this function isSuperKey
because of these two reasons:
- It’s a hard to say Command (on Mac) and Control (on Windows). We need a new term.
- Sublime Text (my previous text editor) uses the term “Super” to mean Command (on Mac) and Control (on Windows). I adopt this term since it makes sense to me.
const isSuperKey = event => {
if (os === 'mac' && event.metaKey) return true
if (os === 'windows' && event.ctrlKey) return true
}
Here’s how you use it:
document.addEventListener('keydown', event => {
if (isSuperKey(event)) {
console.log('Command (Mac) or Control (Windows) Pressed!')
}
})
To detect whether Super is used with another key, you can use the &&
operator in a condition.
document.addEventListener('keydown', event => {
const key = event.key.toLowerCase()
if (isSuperKey(event) && key === 'e') {
console.log('Pressed Super + e!')
}
})
What about the Control key (Mac)?
Windows does not have a key that’s equivalent to Control on Mac. This means you should avoid Mac’s Control key if you want to create keyboard shortcuts that work on all operating systems.
That said, if you find yourself in a situation where Control on Mac is required (and it should not trigger Control on Windows), you can use isCtrlKey
:
const isCtrlKey = event => {
if (os === 'mac' && event.ctrlKey) return true
}
Try not to use Super for keyboard shortcuts
System and browser keyboard shortcuts tend to use Super. Here are some examples:
Shortcut |
Mac |
Windows |
Select all |
Command + a |
Control + a |
Copy |
Command + c |
Control + c |
Add to Bookmarks |
Command + d |
Control + d |
Find: |
Command + f |
Control + f |
Go to address bar |
Command + l |
Control + l |
Minimize |
Command + m |
Windows + ↓ |
Open new window |
Command + n |
Control + n |
Print |
Command + p |
Control + p |
Quit app |
Command + q |
Alt + F4 |
Refresh |
Command + r |
F5 |
Save |
Command + s |
Control + s |
Open new Tab |
Command + t |
Control + t |
Paste |
Command + v |
Control + v |
Close Tab |
Command + w |
Control + w |
Cut |
Command + x |
Control + x |
Undo |
Command + z |
Control + z |
There are very few keys left over, so your choices are limited if you use Super.
If you need to overwrite a keyboard shortcut, you can use preventDefault
to prevent the browser or system shortcut from activating.
document.addEventListener('keydown', event => {
const key = event.key.toLowerCase()
if (isSuperKey(event) && key === 'd') {
event.preventDefault()
console.log('Bookmark functionality prevented')
}
})
Be careful about preventing events from Super keyboard shortcuts. You may prevent some important actions from working. For example, I will get pissed 😡 if you prevented these shortcuts:
Command
+ r
: Refreshes the page
Command
+ t
: Opens a new tab
Also, some browsers don’t allow you to prevent certain actions. This is inconsistent across browsers. Here are some examples:
Command
+ q
always quits the browser (Mac).
Command
+ w
closes a tab in Safari. (But you can prevent Command
+ w
in Chrome).
Command
+ n
opens a new window in Chrome. (But you can prevent Command
+ n
in Safari).
You can’t prevent lots of combinations of keys with Super, so try not to use Super. (Unless the shortcut you’re using is universally accepted).
Don’t use Tab in place of Super
I want to highlight this because I know Asana (a popular task management app) uses Tab as a modifier for their keyboard shortcuts. I suppose they used Tab because they wanted a cross-operating-system modifier for their keyboard shortcuts.
If you do this, you’re preventing the default Tab behaviour that many people use . Don’t break keyboard accessibility this way. Only prevent Tab behaviour when it makes sense (like for the carousel and calculator).
Summary
- Try not to use Super (Command for Mac, Control for Windows) for keyboard shortcuts.
- Use Control (Mac) only if you’re building a Mac-only thing.
- Don’t ever use Tab for keyboard shortcuts.