sveltelean Primitives
Versionv0.2.0 GitHub

Example

Keys in running text

Press / to filter the sidebar and Esc to clear it.

Open the command palette with Ctrl+K, or Cmd+K on macOS.

Move between tabs with ← and →.

<p>Press <kbd data-slean="kbd">/</kbd> to filter the sidebar and
	<kbd data-slean="kbd">Esc</kbd> to clear it.</p>
<p>Open the command palette with
	<kbd data-slean="kbd"><kbd>Ctrl</kbd>+<kbd>K</kbd></kbd>, or
	<kbd data-slean="kbd"><kbd>Cmd</kbd>+<kbd>K</kbd></kbd> on macOS.</p>
<p>Move between tabs with <kbd data-slean="kbd">←</kbd> and <kbd data-slean="kbd">→</kbd>.</p>
Tier 0: the two sources differ only by the stylesheet import. A single key is a <kbd> with text; a combination is a <kbd> holding one <kbd> per key and the plus signs between them.

Why this implementation exists

<kbd> is HTML for user input, and nesting it is HTML for a combination: the outer element is the whole input, the inner ones are the keys. Browsers and screen readers read it as text. The primitive is the drawing of a key and the rule that a combination is drawn key by key.

Where a shortcut exists, it belongs to a control. aria-keyshortcuts on that control announces it; the <kbd> only shows it.

The browser owns

  • the <kbd> element as user input, and the nested form of a key combination
  • the text screen readers read out

Svelte Lean owns

  • kbd.css: the key box with a thicker bottom edge, the combination drawn key by key
  • the contract: key names as text, aria-keyshortcuts on the control
  • documentation

Usage

The markup needs no package. Install @svelte-lean/styles for the stylesheet; @svelte-lean/primitives adds the typed contract and nothing at runtime.

npm install @svelte-lean/styles
stylesheets
import '@svelte-lean/styles/kbd.css';

Write key names as text: Ctrl, Shift, Enter. Symbols such as ⌘ and ⇧ are read differently, or not at all, by screen readers; when you show one, add the name as visually hidden text.

For a combination, put one <kbd> per key inside the root and keep the plus signs as text between them.

Anatomy

PartElementdata-slean-partRequiredNotes
root<kbd data-slean="kbd">–yesOne key as text, or one <kbd> per key for a combination.
key<kbd> inside the root–noDrawn as keys; the root around them draws nothing.

Runtime profile

Tier 0: the key has no behavior module, the Vite plugin maps kbd to no module, and the native-only fixture proves the path ships no Svelte Lean JavaScript.

Accessibility contract

  • <kbd> is text; screen readers read the key names in order, the plus signs included.
  • The shortcut itself is announced from aria-keyshortcuts on the control it activates, not from the <kbd>.
  • Keys are not focusable and have no role.

Keyboard

KeyWhenResult
TabanywherePasses the key by: it is text, not a control

Platform features

FeatureBaselineOutside the target
<kbd>Widely availableNot applicable within the support policy
:has()Baseline 2023, widely available since June 2026A combination is drawn as one box around its keys

Without JavaScript

Fully functional.

Server rendering

Static HTML.

Before hydration

Nothing is attached.

Styling

kbd.css draws a key as a bordered box with a thicker bottom edge in the page font, and, through :has(), draws the inner keys of a combination instead of the root. The tokens it reads:

TokenDefault (light)Applies to
--slean-border-strongvar(--slean-neutral-8)border
--slean-radius-sm0.375remborder-radius
--slean-surfaceoklch(100% 0 0)background
--slean-fgvar(--slean-neutral-12)color
--slean-text-xs0.75remfont-size
--slean-font-weight-medium500font-weight
--slean-fg-mutedvar(--slean-neutral-11)color

Compatibility notes

<kbd> is widely available. :has() is Baseline 2023 and widely available since June 2026; without it a combination is drawn as one box around its keys.

Examples

Shortcut on a control

A key drawn next to a button tells sighted readers the shortcut. For assistive technology the shortcut is aria-keyshortcuts on the control itself; the handler that makes the keys work is the application's.

search-button.html
<!-- The shortcut is announced on the control; the <kbd> only shows it. The keydown
     handler that makes Ctrl+K open the palette is the application's. -->
<button type="button" data-slean="button" data-variant="outline" aria-keyshortcuts="Control+K">
	Search
	<kbd data-slean="kbd"><kbd>Ctrl</kbd>+<kbd>K</kbd></kbd>
</button>

Testing

Source