Skip to content
cennge-ui
GitHubv0.3.1, changelog

Kbd

Keys and shortcuts as key caps: drawn symbols for the eye, key names for screen readers.

Search the docs

Open search
Command KCtrlK
Next or previous result
Arrow down Arrow up
Open the result
Enter
Close
Esc

Any page

Next link or field
Tab
Previous link or field
Shift Tab
  1. Hover a drawn key: its title names it, Command or Arrow down.
  2. A screen reader reads each drawn key by name: Shift Tab is "Shift Tab".
  3. Ctrl, Alt, Esc and Space are written as words; the other eleven are drawn, the same size in every font.
Live: hover a key to read its name.

Field marks

Import
import { Kbd } from "cennge-ui";
Size
1.2 KB gzip for this import, its dependencies aside
Pattern
Native <kbd>; each named key an <abbr> with its full name
SSR
Rendered on the server in the Next.js check; hydrates without a warning
Named keys
Fifteen, from command to right; any other key as text
Symbols
Drawn in SVG, so they fill the cap in any font
Tests
Unit tests; end-to-end in Chromium, Firefox and WebKit, on desktop and phone viewports: kbd

When to use#

Use Kbd wherever the page tells the reader to press something: a shortcut beside a menu item, a hint under a search field, a step in a guide. One Kbd holds one shortcut, modifiers and key together, and screen readers hear it as one phrase: "Command Shift P".

Similar#

  • Snippet is a command to copy and paste, not a key to press.
  • Prose styles a bare <kbd> from Markdown as plain text in a box. Kbd draws the symbols and names them.

Keys and shortcuts#

keys takes the named keys, shown in order; children add anything else, such as a letter. A key that has no name, like F5 or PageDown, is plain text. At size="sm" a cap fits in a line of text.

Command KCommand Shift PCtrlAltTOption F5PageDown

Press Esc to close the dialog, or Enter to save.

shortcuts.tsx
import { Kbd } from "cennge-ui";

export default function KbdShortcuts() {
  return (
    <div className="flex flex-col gap-5">
      <div className="flex flex-wrap items-center gap-3">
        <Kbd keys="command">K</Kbd>
        <Kbd keys={["command", "shift"]}>P</Kbd>
        <Kbd keys={["ctrl", "alt"]}>T</Kbd>
        <Kbd keys="option" />
        <Kbd>F5</Kbd>
        <Kbd>PageDown</Kbd>
      </div>
      <p className="text-sm text-muted">
        Press <Kbd keys="escape" size="sm" /> to close the dialog, or <Kbd keys="enter" size="sm" /> to save.
      </p>
    </div>
  );
}

Command on a Mac, Ctrl elsewhere#

The server does not know the reader's platform. Render the Ctrl version first and switch after hydration, so the server's HTML and the first render agree. The search box at the top of this page does the same.

Search the docs from any page with CtrlK.

platform.tsx
import { useEffect, useState } from "react";
import { Kbd } from "cennge-ui";

export default function SearchHint() {
  // The server cannot know the platform: render Ctrl, then switch after hydration.
  const [isMac, setMac] = useState(false);
  useEffect(() => setMac(/Mac|iPhone|iPad/.test(navigator.platform)), []);

  return (
    <p className="text-sm text-muted">
      Search the docs from any page with{" "}
      <Kbd keys={isMac ? "command" : "ctrl"} size="sm">
        K
      </Kbd>
      .
    </p>
  );
}

Every named key#

Fifteen names; ctrl, alt, escape and space are written as words, as they are on the key itself.

command
Command
shift
Shift
option
Option
ctrl
Ctrl
alt
Alt
enter
Enter
escape
Esc
tab
Tab
backspace
Backspace
delete
Delete
space
Space
up
Arrow up
down
Arrow down
left
Arrow left
right
Arrow right
named-keys.tsx
import { Kbd, type KbdKey } from "cennge-ui";

const keys: KbdKey[] = [
  "command",
  "shift",
  "option",
  "ctrl",
  "alt",
  "enter",
  "escape",
  "tab",
  "backspace",
  "delete",
  "space",
  "up",
  "down",
  "left",
  "right",
];

export default function NamedKeys() {
  return (
    <dl className="grid w-full grid-cols-[repeat(auto-fill,minmax(7.5rem,1fr))] gap-x-8 gap-y-3">
      {keys.map((key) => (
        <div key={key} className="flex items-center justify-between gap-2">
          <dt className="font-mono text-[13px] text-muted">{key}</dt>
          <dd>
            <Kbd keys={key} />
          </dd>
        </div>
      ))}
    </dl>
  );
}

Accessibility#

A drawn symbol is aria-hidden; its key's full name is visually hidden text beside it, followed by a space, so Command Shift K reads "Command Shift K" rather than one word. Each named key is an <abbr> whose title gives its full name on hover, Control for Ctrl and Escape for Esc. Kbd takes no focus and handles no keys: it only shows them.

Props#

PropTypeDefault
keys
KbdKey | KbdKey[]Named keys rendered as symbols, each with its full name for screen readers. Combined with children.
–
size
"sm""md"
"md"