Detect fn and function key simultaneously pressed
I found a way to do this that uses the awesome Karabiner-Elements. This has been so useful for me in many situations, and it works here too.

Karabiner can detect function keys being pressed, and tell whether it's with or without the fn key modifier.

We can make our own "Complex modification" that takes advantage of this:


Complex modifications are stored in ~/.config/karabiner/assets/complex_modifications as json files. Create a file in here with your favourite text editor:

vim ~/.config/karabiner/assets/complex_modifications/detect_fn.json

You need to fill the file with your own rules, here's what mine looks like now:

{
  "title": "The fn keys can control volume of built-in output even when a multi-output device is being used.",
  "rules": [
    {
      "description": "Map fn volume keys to execute applescript which changes volume of built-in output.",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "f10",
            "modifiers": {
              "mandatory": [
                "fn"
              ]
            }
          },
          "to": [
            {
              "shell_command": "osascript -e 'set volume alert volume 0' &amp;&amp; osascript -e 'set volume (alert volume of (get volume settings))*7/100'"
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "f11",
            "modifiers": {
              "mandatory": [
                "fn"
              ]
            }
          },
          "to": [
            {
              "shell_command": "osascript -e 'set volume alert volume ((alert volume of (get volume settings)) - 100/16)' &amp;&amp; osascript -e 'set volume (alert volume of (get volume settings))*7/100'"
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "key_code": "f12",
            "modifiers": {
              "mandatory": [
                "fn"
              ]
            }
          },
          "to": [
            {
              "shell_command": "osascript -e 'set volume alert volume ((alert volume of (get volume settings)) + 100/16)' &amp;&amp; osascript -e 'set volume (alert volume of (get volume settings))*7/100'"
            }
          ]
        }
      ]
    }
  ]
}

It should be obvious how you can replace the keys with whichever ones you want, and you can also replace the shell command with any shell command.
Add the rule into karabiner-elements by


Starting it up
Choosing "Complex Modifications" from the top
Clicking "(+) Add rule"
Enabling the rule you just defined