Keyboard shortcuts with Command and Control modifiers

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

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:

  1. It’s a hard to say Command (on Mac) and Control (on Windows). We need a new term.
  2. 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:

  1. Command + q always quits the browser (Mac).
  2. Command + w closes a tab in Safari. (But you can prevent Command + w in Chrome).
  3. 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

  1. Try not to use Super (Command for Mac, Control for Windows) for keyboard shortcuts.
  2. Use Control (Mac) only if you’re building a Mac-only thing.
  3. Don’t ever use Tab for keyboard shortcuts.