NiftyMenu is the little tool I use to dump a macOS app’s menu bar into an HTML page so I can search it, click through to items, and add callouts for screencasts and product documentation. The latest round of updates brings the UI in line with macOS Tahoe and cleans up a bunch of behavior and script logic.
I wrote NiftyMenu years ago, and did a major update for Ventura. But it was way behind on Liquid Glass and basically wasn’t working anymore.
What it is
Since it’s been a while, let me explain NiftyMenu a bit. It’s a tool specifically for people documenting or blogging about apps (though anybody might get a kick out of it). When you want a screenshot of a menu item, highlighted (maybe with callouts), getting a menu to stick in place and maintain highlight state while you take a screenshot can be tricky, and doing a bunch of screenshots like this can be a pain.
NiftyMenu creates an HTML version of any app’s menu bar. You can click any item to lock it in place, navigate submenus, select items, highlight them, add callouts, and focus the shortcut key. It has dark and light modes, quick search for finding menu items with just the keyboard, customizable desktop images (including random images), and more.
I recommend viewing the pages it produces in Chrome. The styling should work well in any browser, but with Chrome you can just hit ⇧+S to save a screenshot of the currently-focused menu item. It’s super handy. Screenshotting works in Firefox, but the text gets screwy. And it doesn’t work at all in Safari. So use Chrome/Chromium.
At the bottom right of a generated menu page there’s a settings box that appears on hover, and you can change things like light/dark mode, background image, callout type, etc.
NiftyMenu is a Ruby script that generates a web app of sorts. Just one page with all the markup necessary for the menu, and some CSS and JavaScript to enable all of its functionality.
Styling to match Tahoe
The new layout and colors are tuned to feel like Tahoe’s menu bar. The font stack uses SF Pro when available (Tahoe and recent macOS), with sensible fallbacks. Top-level menu items get a soft white overlay on hover with rounded corners instead of a flat accent block; the solid accent is reserved for the selected item (.last). Submenus use the same idea: light grey overlay on hover, accent only on the selected row. Toolbar height, padding, and submenu positioning are adjusted so the overall proportions match the system menus.
Dark mode gets the same treatment: overlay-based hover states and accent only on the selected item. Submenu and divider colors use the new variables so they stay consistent with the rest of the theme.
Backgrounds and overlays
Unsplash deprecated their simpler API for image embeds, so I switched the random wallpaper generator to use Picsum.photos. You can’t do a search, but you can get a random image and apply blur and grayscale to it (NiftyMenu gives you the options when getting a random wallpaper). You can also add a “seed” word, which will stick the image so that it can be retrieved reliably. The seed you enter is stored in browser storage and will automatically be used next time the dialog is opened.
The page background (gradient or desktop image) is now fixed to the viewport, so when the menu list is taller than the window you scroll the content, not the background.
If you use a desktop image, there’s a brightening overlay: a semi-transparent layer with background-blend-mode: overlay so the image reads a bit lighter. You can tweak it (or turn it off) via $desktop-image-overlay and $dark-desktop-image-overlay in your variables. The toolbar strip at the top uses the same overlay color and blend so it sits nicely over the gradient or image.
In light mode, when submenus overlap each other or the parent, the overlap darkens instead of lightening. Submenu uls use mix-blend-mode: multiply and an opaque background so you get a clear light bluish-grey panel that darkens where it stacks.
A few fixes while I was at it
Divider rows no longer highlight on hover or accept clicks. They use pointer-events: none and the click handler bails out for divider targets and list items that only contain a divider.
The script also fixes the case where a bogus shortcut was attached to a divider line and produced blockquotes in the markdown; that combo is now normalized to a plain divider span before processing.
The globe key in shortcuts is no longer an emoji. The script outputs the entity, then swaps it for a <span class="globe-icon"> so CSS can draw the icon with a mask and currentColor, including when the shortcut is in the callout (inverted) state.
There’s a bit more progress reporting now, going to STDERR in Terminal while processing, with a simple bar and step labels: gather, process, convert, write.
What’s missing
In macOS, there are often menu items that change to an alternate option when you hold down the ⌥ key. With the way NiftyMenu gathers items, these all appear in the same menu, not hidden behind a modifier. I spent an hour this morning trying to get that to work, but it doesn’t seem feasible.
I also struggled with overlapping transparencies. In Tahoe, when a submenu’s left edge overlaps the parent menu, the edge appears opaque, or at least at uniform transparency with the submenu. Because the HTML version uses CSS colors with alpha channels, the overlap instead becomes a brighter version of the base color. I played with blend modes and other tricks but couldn’t find a way to replicate this. It’s a very small issue, but one that bugged me. If anyone has suggestions, I’d love to hear them.
There’s a JavaScript API for automating the process of selecting menu items using fuzzy search and even saving the screenshots, so you can create a workflow that generates new screenshots even as menu item names and positions change. It’s not a perfect solution — being able to do it with AppleScript would be better, but not an option here.
I also could have, but didn’t, set it up so you could choose the OS styling to use. It’s always going to use the latest macOS (that it’s been updated for) and not be backward compatible. This seems like a reasonable approach to me.
Give it a shot
If you’re writing documentation or are a blogger who often talks about apps’ menu items and shortcuts, give NiftyMenu a shot. If nothing else, it’s a pretty cool proof of concept.