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
- Hover a drawn key: its title names it, Command or Arrow down.
- A screen reader reads each drawn key by name: Shift Tab is "Shift Tab".
- Ctrl, Alt, Esc and Space are written as words; the other eleven are drawn, the same size in every font.
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
commandtoright; 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
- Source
- src/components/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.
Press Esc to close the dialog, or Enter to save.
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.
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
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.