Skip to content

Kbd

Kbd
Thymeleaf source
<sl:kbd>Esc</sl:kbd>
<sl:kbd>Enter</sl:kbd>
<sl:kbd>/</sl:kbd>
Rendered HTML
<kbd class="kbd">Esc</kbd>
<kbd class="kbd">Enter</kbd>
<kbd class="kbd">/</kbd>

<sl:kbd> renders HTML’s own <kbd> element, so it fits in running text.

In a sentence
Thymeleaf source
<p>Press <sl:kbd>/</sl:kbd> to search.</p>
Rendered HTML
<p>
Press
<kbd class="kbd">/</kbd>
to search.
</p>

Put the keys pressed together in <sl:kbd-group>. It is an outer <kbd>, which is how HTML marks up a combination. Text between the keys, such as +, is up to you.

A key combination
Thymeleaf source
<sl:kbd-group>
<sl:kbd>Ctrl</sl:kbd>
<sl:kbd>Shift</sl:kbd>
<sl:kbd>P</sl:kbd>
</sl:kbd-group>
<sl:kbd-group><sl:kbd>Ctrl</sl:kbd>+<sl:kbd>K</sl:kbd></sl:kbd-group>
Rendered HTML
<kbd class="kbd-group">
<kbd class="kbd">Ctrl</kbd>
<kbd class="kbd">Shift</kbd>
<kbd class="kbd">P</kbd>
</kbd>
<kbd class="kbd-group">
<kbd class="kbd">Ctrl</kbd>
+
<kbd class="kbd">K</kbd>
</kbd>

A key can hold an <sl:icon>. Give the icon a label, as a screen reader has no text to read otherwise. An aria-label on the key itself would not do: <kbd> has no role that takes a name.

Lucide has icons for the usual keys, so you never need to type a symbol: command, option, arrow-big-up (Shift), corner-down-left (Enter), delete (Backspace), arrow-up / arrow-down / arrow-left / arrow-right, and space.

With an iconAn icon on its own has no text, so give the key a name.
Thymeleaf source
<sl:kbd-group>
<sl:kbd><sl:icon name="command" label="Command"/></sl:kbd>
<sl:kbd>K</sl:kbd>
</sl:kbd-group>
Rendered HTML
<kbd class="kbd-group">
<kbd class="kbd">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Command">
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3"></path>
</svg>
</kbd>
<kbd class="kbd">K</kbd>
</kbd>

A key can sit next to a button’s label, to show its shortcut. Hide the key from screen readers with aria-hidden="true", or it becomes part of the button’s name (“Accept Enter”), and name the shortcut in aria-keyshortcuts on the button instead. An icon in a hidden key needs no label. aria-keyshortcuts only announces the shortcut: listening for the key is up to your own script.

In a buttonThe shortcut goes in aria-keyshortcuts; the key itself is hidden from screen readers.
Thymeleaf source
<sl:button aria-keyshortcuts="Enter">
Accept <sl:kbd aria-hidden="true"><sl:icon name="corner-down-left"/></sl:kbd>
</sl:button>
<sl:button variant="outline" aria-keyshortcuts="Escape">
Cancel <sl:kbd aria-hidden="true">Esc</sl:kbd>
</sl:button>
Rendered HTML
<button class="button" type="button" aria-keyshortcuts="Enter">
Accept
<kbd class="kbd" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 4v7a4 4 0 0 1-4 4H4"></path>
<path d="m9 10-5 5 5 5"></path>
</svg>
</kbd>
</button>
<button class="button" type="button" data-variant="outline" aria-keyshortcuts="Escape">
Cancel
<kbd class="kbd" aria-hidden="true">Esc</kbd>
</button>

sl:kbd declares no props; every attribute passes through.

sl:kbd-group declares no props; every attribute passes through.