jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

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.

install — kbd

$npx jixoai-ui add kbd

https://ui.jixoai.com/r/kbd.json

native <kbd> zero parsing variant ladder · tonal default

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-usage.svelte svelte
<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> exits

demo

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

keyboard bindings and their glyphs
search/
shortcut sheetShift?
immediate exit⌃C
kbd-shortcut-rows-demo.svelte svelte
<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.

⌘+KorShift?
tonal⌘KoutlineShift?fillEnter

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.

usage
<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> exits

theming

Density and tokens

xs
K
default
K
lg
K
TokenDefaultSource
--jx-tonalvar(--primary)component
--jx-gapdensity scaledensity
--jx-text-secondarydensity scaledensity
--jx-line-secondarydensity scaledensity

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

PropertyTypeDefaultDescription
variant 'fill' | 'tonal' | 'outline''tonal' · Own default, not ambientPaint-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

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity 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).

PropertyTypeDefaultDescription
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).

one real query() case
<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.

kbd-query-demo.svelte svelte
<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

⌘ K
shift
squircle
auto
kbd-universal.svelte svelte
<!-- 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

KeyAction
—Non-interactive by contract — a glyph, never a control; it takes no focus and no keys

ARIA

AttributeValueDescription
kbdnative elementCommunicates keyboard input to assistive tech with zero added ARIA — no role, no state.
combination readingkey + 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 propstitle / data-* / global ARIAFlow through to the element verbatim — a title tooltip or an aria-label override is the consumer’s call.
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h