registry:ui · General
kbd — the element, chipped
A native <kbd> — the element whose entire meaning is 'this is keyboard input' — on the grammar's variant ladder: tonal (12%/45% primary tint) by default, fill and outline beside it, over the engraved geometry (1px border + the --shadow-engrave inset, mono). Deliberately no key-parsing and no platform detection (⌘/Ctrl string opinions belong to the caller); keys compose by hand.
$npx jixoai-ui add kbd
https://ui.jixoai.com/r/kbd.json
overview
Overview
The native <kbd> element, chipped: zero parsing opinions, an own engraved voice, and a paint ladder that re-derives with the scope.
The semantics are the platform's: a native <kbd> means "keyboard input" to assistive
tech with zero added ARIA — combinations compose by hand
(<kbd>⌘</kbd> + <kbd>K</kbd>),
and the + separators are prose. The family deliberately ships NO key-parsing and NO
platform detection (⌘/Ctrl string opinions belong to the caller); title and data-*
flow through rest props.
The voice is the family's OWN, not the context's — measured 12px inside a 13.5px
prose run and a 13px table row alike, because the atom pins the --jx-text-secondary density kernel (the stale
"inherits font-size" caption is falsified and corrected in the axes table). The
geometry is the engraving: 1px hairline frame, the own 2px corner (promotion seam),
and the --shadow-engrave inset pair — a glyph
incised into the plane, not lifted off it. Density is the live ladder (10/12/14px
voice, 8/12/16px padding measured).
The ladder is tonal (primary tint) by default, fill and outline beside it — a rung is
the SOLE border-color source, and semantic hue injects from outside via jx-hue-*
utilities, never as a variant name. Under a scoped .dark the tonal voices re-derive
with the scope's primary (the token stream resolves per element — measured), while
the engrave keeps its literal inset pair. Kinship: chip and press-button (the byte-aligned variant map).
kbd
Shortcut rows in prose, tables, menus — the glyph carries its OWN voice: the --jx-text-secondary kernel (12px at the default rung), density-governed, not inherited from the context.
⌘ + K opens the palette
Shift + ? for shortcuts
Esc closes any surface on this site — dialogs, menus, sheets share the law.
<Kbd>⌘</Kbd> + <Kbd>K</Kbd> opens the palette
<Kbd>Shift</Kbd> + <Kbd>?</Kbd> for shortcuts
<Kbd variant="fill">Enter</Kbd> commits · <Kbd variant="outline">Esc</Kbd> exitsdemo
Shortcut rows
The glyph's natural habitats: menu items that hint their accelerator, tables of bindings, and prose. Every instance below is the same component voicing its own density-kernel tone — the context does not resize it (the falsified-inheritance note in the axes table is the receipt).
kbd · shortcut rows
| search | / |
|---|---|
| shortcut sheet | Shift? |
| immediate exit | ⌃C |
<script lang="ts">
import Kbd from '@ui/kbd.svelte';
</script>
<div class={cx(rt.col24)}>
<div class={cx(rt.flex, rt.wFull, rt.maxWMd, rt.col, rt.gap4, rt.frame)}>
<button
type="button"
class="flex items-center justify-between gap-4 border-b border-border px-3 py-2 text-left text-[13px] hover:bg-muted/50"
>
<span>open the command palette</span>
<span class={cx(rt.flex, rt.gap4)}><Kbd>⌘</Kbd><Kbd>K</Kbd></span>
</button>
<button
type="button"
class="flex items-center justify-between gap-4 border-b border-border px-3 py-2 text-left text-[13px] hover:bg-muted/50"
>
<span>toggle the theme</span>
<span class={cx(rt.flex, rt.gap4)}><Kbd>⌘</Kbd><Kbd>⇧</Kbd><Kbd>L</Kbd></span>
</button>
<button
type="button"
class="flex items-center justify-between gap-4 px-3 py-2 text-left text-[13px] hover:bg-muted/50"
>
<span>close this surface</span>
<Kbd>Esc</Kbd>
</button>
</div>
<table class={cx(rt.wFull, rt.maxWMd, rt.text125)}>
<caption class={cx(rt.srOnly)}>keyboard bindings and their glyphs</caption>
<tbody>
<tr class={cx(rt.tBorder)}>
<th scope="row" class={cx(rt.bBorder, rt.px8, rt.py6, rt.textLeft, rt.weightNormal, rt.inkMuted)}>search</th>
<td class={cx(rt.bBorder, rt.px8, rt.py6)}><span class={cx(rt.flex, rt.gap4)}><Kbd>/</Kbd></span></td>
</tr>
<tr class={cx(rt.tBorder)}>
<th scope="row" class={cx(rt.bBorder, rt.px8, rt.py6, rt.textLeft, rt.weightNormal, rt.inkMuted)}>shortcut sheet</th>
<td class={cx(rt.bBorder, rt.px8, rt.py6)}><span class={cx(rt.flex, rt.gap4)}><Kbd>Shift</Kbd><Kbd>?</Kbd></span></td>
</tr>
<tr class={cx(rt.tBorder)}>
<th scope="row" class={cx(rt.px8, rt.py6, rt.textLeft, rt.weightNormal, rt.inkMuted)}>immediate exit</th>
<td class={cx(rt.px8, rt.py6)}><Kbd>⌃</Kbd><Kbd>C</Kbd></td>
</tr>
</tbody>
</table>
</div>types
Keyboard glyphs
Kbd is a native semantic element; compose one key or a chord from several instances.
usage
Usage
The platform gives the semantics: <kbd> means keyboard input to assistive tech with zero ARIA. We add only the ladder paint — 1px border, the engrave inset, mono — and nothing else.
<Kbd>⌘</Kbd> + <Kbd>K</Kbd> opens the palette
<Kbd>Shift</Kbd> + <Kbd>?</Kbd> for shortcuts
<Kbd variant="fill">Enter</Kbd> commits · <Kbd variant="outline">Esc</Kbd> exitstheming
Density and tokens
| Token | Default | Source |
|---|---|---|
| --jx-tonal | var(--primary) | component |
| --jx-gap | density scale | density |
| --jx-text-secondary | density scale | density |
| --jx-line-secondary | density scale | density |
api
Kbd props
The generated meta carries 13 props (12 named + the synthesized rest); the hand table's density row folds into the shared universal section beneath (its text is the frozen ambient-scope vocabulary, pinned by the ambient matrix, task 30) — variant and class render here; the family-specific density MEASUREMENTS live in the axes table.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| variant | 'fill' | 'tonal' | 'outline' | 'tonal' · Own default, not ambient | Paint-ladder rung; tonal (primary) is the default. Own default, not ambient (the glyph is outside the paint zone’s frozen availability table). Semantic hue injects via jx-hue-* classes, never as a variant name. |
| class | string | — | Adds consumer classes. |
Universal props
| Property | Type | Default | Description |
|---|---|---|---|
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | the base scale — root font-size; parts size in em |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' · ambient scope | corner geometry (CSS corner-shape; §14 degrade table) |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | corner size; auto = the concentric broadcast (§3) |
| density | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | spacing/leading scale over the kernel channels (§4) |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' · ambient scope | the hue axis of the fixed oklch primary system (§5) |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' · ambient scope | light/dark profile; system = the JS-mutable global (§6) |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' · ambient scope | official M3 levels over the surface ladder (§7) |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' · ambient scope | intensity across the motion kernels (§8) |
axes
The eight axes on kbd
Density is the one consumed ladder — the glyph's whole voice rides the SECONDARY kernel channels (measured 10/12/14px, 8/12/16px padding). Size is the §11 echo with a built-in falsification: the kbd renders 12px inside any context (the stale inheritance caption corrected here). The corner is the own 2px promotion seam; the shadow the own engrave tier; shape/color/elevation/motion stamp-and-supply; the tonal ladder is the RE-DERIVING theme voice (flips with the scope's primary, measured).
| Property | Type | Default | Description |
|---|---|---|---|
| density | 'small' | 'medium' | 'large' | 'auto' | number (+ the five legacy spellings) | 'auto' | CONSUMED — the glyph's whole voice rides the SECONDARY kernel channels: measured across xs/default/lg — fontSize 10 / 12 / 14px, line-height 13.5 / 18 / 21px, inline padding 8 / 12 / 16px (--jx-gap). The family own is none: no opinion stamps nothing and the ambient scope channel flows (measured data-density null under ambient scope boxes). Number unit: coefficient. |
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' | OWN VOICE, NOT INHERITANCE (the stale-caption falsification): the old page text claimed the chip 'inherits font-size from context — shrinks in table cells and grows in heroes'. Measured FALSE: the kbd renders 12px inside a 13.5px prose context and inside a 13px table row alike — the fontSize atom pins --jx-text-secondary (the density kernel), so the §11 stamp moves the root and the glyph's voice stays put. Context never scales it. Number unit: px. |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' | SUPPLY-ONLY — stamps the carriers; zero readers (grep receipt: the family ships no css file; the atoms read no shape channel). Number unit: none. |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' | OWN 2px CORNER (measured borderRadius: 2px at every lane) — the corner rides the promotion seam var(--kbd-radius, 2px), NOT the axis carrier; an explicit radius lane supplies through the carriers for composed descendants only. Number unit: px. |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' | SUPPLY-ONLY — the axis carrier is unread (grep receipt). Semantic hue injects from OUTSIDE via jx-hue-* utilities (the tonal ladder re-tints because its mix reads --jx-tonal → primary); never as a variant name. Number unit: hue degrees. |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' | THE BRIDGE, RE-DERIVING — measured under a scoped .dark: the tonal ladder FLIPS with the scope (background mix 0.6489-family → 0.7044-family, ink follows the scope's primary) because the tonal voices read the --jx-tonal → primary STREAM, which re-resolves per element — unlike the frozen-pole families whose typed tokens carry literal values. The engrave shadow keeps its literal inset pair. system/auto ride tree inheritance. No number lane. |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' | OWN ENGRAVE TIER, AXIS UNREAD — the glyph's shadow is the elevation grammar's ENGRAVE token (--jx-shadow-engrave, the measured inset pair), not an axis lane; the --jx-elevation-effective carrier is unread (grep receipt). A glyph incised into the plane, not lifted off it. Number unit: dp. |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' | SUPPLY-ONLY — stamps --jx-motion-effective; zero readers and ZERO transition declarations in the family (grep receipt: the static glyph has nothing to animate). Number unit: coefficient. |
Receipts: the density ladder (voice/line/padding), the own-voice falsification (12px in 13.5px and 13px contexts), the 2px corner and the scoped-.dark re-derivation were measured on this page's served DOM (probe, task 30); the supply-only rows carry grep receipts over ui/kbd/ (a family with NO css file — atoms + the promotion seam are the whole surface). The universal demo folds in below, with a query() seat: the size lane rides the md viewport key (48rem).
<script lang="ts">
import Kbd from '@ui/kbd.svelte';
import { query } from '@lib/universal-props-query.svelte';
</script>
<!-- below 48rem the base (14px) applies; at 48rem+ the md case (18px)
wins — the §11 echo the root stamps (the glyph's own voice stays
the secondary kernel channel) -->
<Kbd size={query({ md: 18 }, 14)}>⌘</Kbd>kbd · query()
Media keys are min-width: below 48rem the base applies — the root stamp reads 14px; at 48rem and wider the md case wins — 18px. The number lane goes bare (results infer); string lanes take both generics. Resize across 48rem.
<script lang="ts">
import Kbd from '@ui/kbd.svelte';
import { query } from '@lib/universal-props-query.svelte';
</script>
<!-- below 48rem the base (14px) applies; at 48rem+ the md case (18px)
wins — the §11 echo the root stamps (the glyph's own voice stays
the secondary kernel channel) -->
<Kbd size={query({ md: 18 }, 14)}>⌘</Kbd>Kbd · universal props
<!-- the eight-axis surface on the glyph -->
<Kbd size={14} density="small">⌘</Kbd>
<Kbd size="large" radius="medium">K</Kbd>a11y
Accessibility
The semantics are the element's own: a native kbd announces keyboard input with zero added ARIA — the cost of compose-by-hand is that each key is its own announcement.
Keyboard
| Key | Action |
|---|---|
| — | Non-interactive by contract — a glyph, never a control; it takes no focus and no keys |
ARIA
| Attribute | Value | Description |
|---|---|---|
| kbd | native element | Communicates keyboard input to assistive tech with zero added ARIA — no role, no state. |
| combination reading | key + key (prose) | Each key is its own kbd and the + is literal text — screen readers announce the keys as text in reading order; the separator is the author’s word. |
| rest props | title / data-* / global ARIA | Flow through to the element verbatim — a title tooltip or an aria-label override is the consumer’s call. |