Interactive Playground

Press any shortcut or navigational key on your keyboard (e.g. , SHIFT + TAB, CMD + A, SHIFT + CMD + T). Click the stage area below to focus and capture keystrokes—while focused, keystrokes are prevented from bubbling up so you can safely test keys like SPACE, TAB, or arrow keys without scrolling the page.

Live Keystroke Visualizer
Click to capture keys
Press a shortcut or arrow key (e.g. , SHIFT + TAB, CMD + A)… Click this area to focus & capture keys (prevents SPACE or arrows from scrolling the page)

Configuration

Base configuration

Style

Animation

Misc

Code

<show-keystrokes position="normal" theme="modern" color-scheme="light"></show-keystrokes>

Features

Configurable Keystroke Display

Choose what to show via keystrokes: Shortcuts & Navigational (default when omitted), all keystrokes, shortcuts only, navigational keys only, or none.

macOS & Windows Aware

Automatically adapts modifier names to macOS (CMD, SHIFT, ALT, CTRL) and Windows/Linux (CTRL, SHIFT, ALT, WIN), or override via platform.

Full Stylability & Themability

Customize every detail using CSS Custom Properties and CSS Shadow Parts (::part()), or pick from the built-in Modern and Mechanical themes (each with Light & Dark variants).

Positioning, Sizes & Auto-Hide

Pin overlays to the viewport (default viewport top right), anchor to the pointer via position="pointer", or render in normal flow with position="normal".

Declarative HTML or create() API

Drop <show-keystrokes> directly into your HTML or dynamically instantiate and append it from JavaScript using create(options, parentElement).

Powered by Popovers

Renders viewport and pointer overlays in the browser’s Top Layer via the Popover API (.showPopover() / .hidePopover()) so keystrokes never suffer from z-index or stacking-context issues.

Installation & Setup

npm install show-keystrokes

Import the package to automatically register the <show-keystrokes> custom element:

import 'show-keystrokes';

Attributes & Configuration

Configure <show-keystrokes> declaratively using HTML attributes or dynamically via JavaScript properties.

Attribute Default Values / Description
keystrokes (no value) (no value) (Shortcuts & Navigational), "all" (All keystrokes), "shortcuts" (Shortcuts only), "navigational" (Navigational Keys only), or "none" (Nothing)
theme "modern" "modern" (Modern Keyboard) or "mechanical" (Mechanical Keyboard)
color-scheme "auto" "light", "dark", or "auto"
size "large" "small", "medium", "large", "x-large", or "xx-large" (or omit and set CSS font-size)
position "viewport top right" "viewport" (or "viewport <top|center|bottom> <left|center|right>", defaults to viewport top right), "pointer" (or "pointer <top|center|bottom> <left|center|right>"), or "normal"
hide-delay 1250 Duration in milliseconds before the pressed keystroke starts fading out (0 disables auto-hide)
hide-duration 200 Duration in milliseconds of the fade-out transition
platform "auto" "mac" (uses CMD), "windows" (uses CTRL), or "auto"
notation "symbols" "symbols" (e.g. , , , , , ) or "text" (e.g. CMD, SHIFT, TAB, ENTER)
keys "" Keystroke string to display (e.g. "SHIFT + TAB", "CMD + A", "→"), also reflected via el.keys
static false Boolean attribute (and reflected el.static property) that renders static keycaps in normal document flow without attaching keyboard listeners or auto-hiding
disabled false Boolean attribute (and reflected el.disabled property) that disables the component and detaches all event listeners

Stylability

Customize the look and feel of <show-keystrokes> from the outside using CSS Custom Properties (--show-keystrokes-*) or by targeting internal elements directly via CSS Shadow Parts (::part()). You can also scale the entire component proportionally by omitting the size attribute and setting font-size directly on <show-keystrokes>.

CSS Custom Properties

Use the interactive controls below to tweak the --show-keystrokes-* CSS Custom Properties on a live static instance and copy the generated CSS.

Interactive CSS Custom Properties Styler

Custom Property Controls

Keycap Surface & Colors
Default
Default
Dimensions & Spacing (Lengths)
Modifier Keycap Overrides
Default (Inherits)
Default (Inherits)
Typography & Separator (+)
Default
Positioning and behavior
Note: Overrides the hide-duration attribute if set.

Generated CSS

show-keystrokes {
  /* Adjust any control above to generate custom property overrides */
}

CSS Shadow Parts (::part()) & Anatomy

All internal elements of <show-keystrokes> are exposed for external styling through ::part() pseudo-elements (see live ::part() examples below). Hover any label below to highlight the corresponding part:

+ + K <show-keystrokes> ::part(anchor) ::part(container) ::part(modifier) ::part(key) ::part(primary) ::part(separator)
Selector / Shadow Part Element Description
<show-keystrokes> <show-keystrokes> The custom element host itself, containing both ::part(anchor) and ::part(container) inside its Shadow DOM
::part(anchor) <div class="anchor"> The positioning anchor element used when position is set to viewport (spans the full viewport) or pointer (tracks the cursor with --show-keystrokes-anchor-size)
::part(container) <div class="container"> The top-layer popover flex container holding all rendered <kbd> keycaps and + separators
::part(key) <kbd class="key"> Every rendered keycap element (matches both modifier keys and primary keys)
::part(modifier) <kbd class="key is-modifier"> Modifier keycap elements (e.g. /CMD, /SHIFT, /OPT/ALT, /CTRL, 🌐︎/FN, /WIN). Can also be compounded as ::part(key modifier)
::part(primary) <kbd class="key"> The non-modifier primary keycap element (e.g. A, K, /TAB, , SPACE). Can also be compounded as ::part(key primary)
::part(separator) <span class="separator"> The + separator element between keycaps

Examples

Built-In Themes (Light & Dark Variants)

<show-keystrokes> ships with two built-in themes: Modern (theme="modern") and Mechanical Keyboard (theme="mechanical"), each with both Light and Dark variants.

Theme 1 · Light

Modern (Light)

theme="modern" color-scheme="light"

White rounded squares with grey text and subtle keycap elevation.

Theme 1 · Dark

Modern (Dark)

theme="modern" color-scheme="dark"

Black rounded squares with lightgrey text mimicking backlit keys.

Theme 2 · Light

Mechanical Keyboard (Light)

theme="mechanical" color-scheme="light"

Sculpted off-white keycaps with deep 3D keywell dish and slate modifier accents.

Theme 2 · Dark

Mechanical Keyboard (Dark)

theme="mechanical" color-scheme="dark"

Carbon keycaps with high-contrast legends and indigo modifier keycaps.

macOS vs. Windows & Key Label Notation

<show-keystrokes> automatically detects the user's operating system and defaults to symbol glyphs (notation="symbols", , , , , ). Set notation="text" to render text labels (CMD, SHIFT, TAB, ENTER), or explicitly set platform="mac" / platform="windows".

macOS Symbols (platform="mac" — Default)
macOS Text (platform="mac" notation="text")
Windows Text (platform="windows" notation="text")

Custom Styling via CSS ::part() & Variables

Style keys using CSS Custom Properties or target ::part(key), ::part(modifier), and ::part(separator) directly.

Neon Cyber Custom Style
Pill Gradient Custom Style
show-keystrokes.custom-neon::part(key) {
  background: #0f172a;
  color: #38bdf8;
  border: 1px solid #0284c7;
  box-shadow: 0 0 12px rgba(56, 189, 248, 0.35), 0 2px 0 #0369a1;
}

show-keystrokes.custom-neon::part(modifier) {
  color: #f472b6;
  border-color: #db2777;
}

JavaScript API

import { create } from 'show-keystrokes';

// Dynamically create & append a <show-keystrokes> element
const el = create(
  {
    keystrokes: 'all',
    theme: 'modern',
    colorScheme: 'dark',
    size: 'large',
    position: 'viewport top right',
  },
  document.body
);

// Programmatically display a keystroke
el.showKeys('SHIFT + TAB');
el.keys = 'CMD + A';

// Enable or disable listening (reflects to the `disabled` attribute)
el.disabled = true;
el.disabled = false;

// Clear display
el.clear();

// Listen for keystroke events
el.addEventListener('keystroke', (e) => {
  console.log(e.detail.label);    // e.g. "SHIFT + TAB"
  console.log(e.detail.keys);     // e.g. ["SHIFT", "TAB"]
  console.log(e.detail.category); // "shortcut" | "navigation" | "keystroke"
});

Showing static keystrokes

Use the keys and static attributes on <show-keystrokes> to render static keycaps in documentation, tutorials, or UI hints without attaching keyboard event listeners or auto-hiding.

Static Keycap Examples Declarative
Right Arrow Key
Hold SHIFT + Hit TAB
Hold CMD + Hit A
Hold SHIFT + CMD + Hit T
<show-keystrokes keys="→" static></show-keystrokes>
<show-keystrokes keys="SHIFT + TAB" static></show-keystrokes>
<show-keystrokes keys="CMD + A" static></show-keystrokes>
<show-keystrokes keys="SHIFT + CMD + T" static></show-keystrokes>

Use on Any Webpage

Bookmarklet

<show-keystrokes> is also available as a bookmarklet for when you want to inject it onto any webpage without modifying the page’s code or installing anything. Drag the button below to your browser’s bookmarks toolbar—clicking it on any page dynamically imports create from https://cdn.jsdelivr.net/npm/show-keystrokes/index.js and appends a <show-keystrokes> instance with the default positioning and theme applied.

Show Keystrokes ← Drag this button to your bookmarks toolbar
if (!document.getElementById('show-keystrokes-bookmarklet')) {
  import('https://cdn.jsdelivr.net/npm/show-keystrokes/index.js')
    .then(({ create }) => create({ id: 'show-keystrokes-bookmarklet' }))
    .catch((err) => alert(`Failed to load show-keystrokes: ${err.message}`));
}

Extension

Note: The extension is currently pending review by Google for the Chrome Web Store. The link will become active once the review is complete.

<show-keystrokes> is also available as a browser extension for when you want to inject it onto any webpage without modifying the page’s code—perfect for live demos, talks, and screen casting. The extension is available on the Chrome Web Store.

Compared to the bookmarklet, the browser extension offers several key advantages:

  • Persists across navigations: Automatically re-injects <show-keystrokes> as you navigate between pages on an enabled origin—no need to re-click the bookmarklet on every page load.
  • Per-origin configuration & overrides: Customize keystrokes, position, positionArea, and size for individual websites directly from the extension popup, with your settings saved and restored automatically on future visits.
  • Configurable global defaults: Set your preferred default options (keystrokes, position, size, theme, color-scheme, hide-delay, and hide-duration), preview them live, and manage saved per-origin configurations from the extension’s Settings page.
  • Quick keyboard shortcut & status indicator: Press SHIFT + CMD + K (macOS) or SHIFT + CTRL + K (Windows/Linux) to toggle <show-keystrokes> on or off at any time, with a green status badge on the toolbar icon showing when it is active.
  • Works on strict CSP websites: Bundles <show-keystrokes> locally inside the extension so it works reliably even on websites whose Content Security Policy blocks external CDN scripts.