07 / 20
All 20 in 20 Tailwind CSS Kbd Keys
- 01Tailwind CSS Kbd Tag Styling for Inline Keyboard Keys
- 02Tailwind 3D Keycap Button with Press-Down Effect
- 03Tailwind Keyboard Shortcut Combo with Plus Separators
- 04Flat Minimalist Tailwind Kbd Key for Body Text
- 05Responsive Tailwind Kbd Sizing with Em Units
- 06Tailwind Mac Cmd vs Windows Ctrl Shortcut Toggle
- 07Tailwind Arrow Keys and Navigation Key Layout
- 08Auto-Detect OS Keyboard Shortcuts (Cmd or Ctrl) in Tailwind
- 09Tailwind Keyboard Layout with Function Keys and Space Bar
- 10Tailwind Icon Keycaps with Inline SVG
- 11Tailwind Search Input with Cmd+K Shortcut Hint
- 12Tailwind Keyboard Shortcuts Cheat Sheet Grid
- 13Tailwind Tooltip with Keyboard Shortcut Hint
- 14Tailwind Keyboard Shortcut Settings Table
- 15Live Key Press Visualizer with Tailwind CSS
- 16Neumorphic Keycap Design in Tailwind CSS
- 17Glassmorphism Keyboard Keys in Tailwind CSS
- 18Retro Typewriter Round Keys in Tailwind CSS
- 19Terminal-Style Monospace Kbd Keys in Tailwind
- 20Dark Mode Kbd Keys with Tailwind CSS Variables
Tailwind Arrow Keys and Navigation Key Layout
The inverted-T arrow cluster and the six-key navigation block, laid out on explicit grid tracks so the shape survives every viewport. One [--u:clamp(…)] unit sizes every cap through size-(--u), and each arrow glyph is aria-hidden with a spoken name beside it.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="kbd-07 relative w-full min-h-svh scheme-light kbd07-dark:scheme-dark bg-kbd07-bg text-kbd07-ink font-kbd07-sans" aria-label="Arrow keys and navigation glyphs demo">
<div class="grid min-h-svh place-items-center px-5 pt-20 pb-12">
<div class="grid w-full min-w-0 max-w-[46rem] gap-4 sm:grid-cols-2">
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Arrow cluster</h2>
<div class="grid grid-cols-[repeat(3,var(--u))] gap-1.5 [--u:clamp(44px,12vw,56px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-1 size-(--u) text-xl"><span aria-hidden="true">↑</span><span class="sr-only">Arrow up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-1 row-start-2 size-(--u) text-xl"><span aria-hidden="true">←</span><span class="sr-only">Arrow left</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-2 size-(--u) text-xl"><span aria-hidden="true">↓</span><span class="sr-only">Arrow down</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-3 row-start-2 size-(--u) text-xl"><span aria-hidden="true">→</span><span class="sr-only">Arrow right</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Explicit grid tracks — the inverted T survives every viewport.</p>
</section>
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Navigation</h2>
<div class="grid w-full max-w-[15rem] grid-cols-3 gap-1.5 [--u:clamp(44px,12vw,52px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Insert</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Home</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↑</span><span class="sr-only">up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Delete</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">End</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↓</span><span class="sr-only">down</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Word labels get their own grid, in the order they sit on a full-size board.</p>
</section>
</div>
</div>
<div class="absolute top-3.5 right-4 z-10">
<input id="kbd-07-theme" type="checkbox" class="peer sr-only">
<label for="kbd-07-theme" class="inline-flex min-h-11 cursor-pointer select-none items-center gap-2.5 rounded-full border border-current/55 px-4 font-sans text-[11px] font-bold uppercase leading-none tracking-[0.16em] text-kbd07-ink transition-colors hover:border-current peer-focus-visible:outline-3 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-kbd07-acc">
<span aria-hidden="true" class="size-3 flex-none rounded-full bg-current transition-[background-color,box-shadow] duration-300 kbd07-dark:bg-transparent kbd07-dark:shadow-[inset_-4px_-2px_0_0_currentColor] motion-reduce:transition-none"></span>
<span class="kbd07-dark:hidden">Light</span><span class="hidden kbd07-dark:inline">Dark</span><span class="sr-only"> theme</span>
</label>
</div>
</section><section class="kbd-07 relative w-full min-h-svh scheme-light kbd07-dark:scheme-dark bg-kbd07-bg text-kbd07-ink font-kbd07-sans" aria-label="Arrow keys and navigation glyphs demo">
<div class="grid min-h-svh place-items-center px-5 pt-20 pb-12">
<div class="grid w-full min-w-0 max-w-[46rem] gap-4 sm:grid-cols-2">
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Arrow cluster</h2>
<div class="grid grid-cols-[repeat(3,var(--u))] gap-1.5 [--u:clamp(44px,12vw,56px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-1 size-(--u) text-xl"><span aria-hidden="true">↑</span><span class="sr-only">Arrow up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-1 row-start-2 size-(--u) text-xl"><span aria-hidden="true">←</span><span class="sr-only">Arrow left</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-2 size-(--u) text-xl"><span aria-hidden="true">↓</span><span class="sr-only">Arrow down</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-3 row-start-2 size-(--u) text-xl"><span aria-hidden="true">→</span><span class="sr-only">Arrow right</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Explicit grid tracks — the inverted T survives every viewport.</p>
</section>
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Navigation</h2>
<div class="grid w-full max-w-[15rem] grid-cols-3 gap-1.5 [--u:clamp(44px,12vw,52px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Insert</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Home</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↑</span><span class="sr-only">up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Delete</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">End</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↓</span><span class="sr-only">down</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Word labels get their own grid, in the order they sit on a full-size board.</p>
</section>
</div>
</div>
<div class="absolute top-3.5 right-4 z-10">
<input id="kbd-07-theme" type="checkbox" class="peer sr-only">
<label for="kbd-07-theme" class="inline-flex min-h-11 cursor-pointer select-none items-center gap-2.5 rounded-full border border-current/55 px-4 font-sans text-[11px] font-bold uppercase leading-none tracking-[0.16em] text-kbd07-ink transition-colors hover:border-current peer-focus-visible:outline-3 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-kbd07-acc">
<span aria-hidden="true" class="size-3 flex-none rounded-full bg-current transition-[background-color,box-shadow] duration-300 kbd07-dark:bg-transparent kbd07-dark:shadow-[inset_-4px_-2px_0_0_currentColor] motion-reduce:transition-none"></span>
<span class="kbd07-dark:hidden">Light</span><span class="hidden kbd07-dark:inline">Dark</span><span class="sr-only"> theme</span>
</label>
</div>
</section>@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400..700&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400..700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
grid-template-areasbecamecol-start-*/row-start-*on each key — the same placement, readable on the element.- The
--ucustom property moved onto the grid as an arbitrary property and is read with v4'ssize-(--u)shorthand. - UI upgrade: the navigation block now follows the real 2×3 layout (Insert · Home · Page Up / Delete · End · Page Down) instead of an arbitrary order.
- UI upgrade: caps gained a convex gradient and soft drop, and the two blocks became matched cards that stack below 640px.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Arrow Keys and Navigation Key Layout
Source: https://codefronts.com/snippets/tailwind-css-kbd-keys/tailwind-arrow-keys-navigation-key-layout/
The inverted-T arrow cluster and the six-key navigation block, laid out on explicit grid tracks so the shape survives every viewport. One [--u:clamp(…)] unit sizes every cap through size-(--u), and each arrow glyph is aria-hidden with a spoken name beside it.
## HTML
```html
<section class="kbd-07 relative w-full min-h-svh scheme-light kbd07-dark:scheme-dark bg-kbd07-bg text-kbd07-ink font-kbd07-sans" aria-label="Arrow keys and navigation glyphs demo">
<div class="grid min-h-svh place-items-center px-5 pt-20 pb-12">
<div class="grid w-full min-w-0 max-w-[46rem] gap-4 sm:grid-cols-2">
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Arrow cluster</h2>
<div class="grid grid-cols-[repeat(3,var(--u))] gap-1.5 [--u:clamp(44px,12vw,56px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-1 size-(--u) text-xl"><span aria-hidden="true">↑</span><span class="sr-only">Arrow up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-1 row-start-2 size-(--u) text-xl"><span aria-hidden="true">←</span><span class="sr-only">Arrow left</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-2 size-(--u) text-xl"><span aria-hidden="true">↓</span><span class="sr-only">Arrow down</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-3 row-start-2 size-(--u) text-xl"><span aria-hidden="true">→</span><span class="sr-only">Arrow right</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Explicit grid tracks — the inverted T survives every viewport.</p>
</section>
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Navigation</h2>
<div class="grid w-full max-w-[15rem] grid-cols-3 gap-1.5 [--u:clamp(44px,12vw,52px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Insert</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Home</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↑</span><span class="sr-only">up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Delete</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">End</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↓</span><span class="sr-only">down</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Word labels get their own grid, in the order they sit on a full-size board.</p>
</section>
</div>
</div>
<div class="absolute top-3.5 right-4 z-10">
<input id="kbd-07-theme" type="checkbox" class="peer sr-only">
<label for="kbd-07-theme" class="inline-flex min-h-11 cursor-pointer select-none items-center gap-2.5 rounded-full border border-current/55 px-4 font-sans text-[11px] font-bold uppercase leading-none tracking-[0.16em] text-kbd07-ink transition-colors hover:border-current peer-focus-visible:outline-3 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-kbd07-acc">
<span aria-hidden="true" class="size-3 flex-none rounded-full bg-current transition-[background-color,box-shadow] duration-300 kbd07-dark:bg-transparent kbd07-dark:shadow-[inset_-4px_-2px_0_0_currentColor] motion-reduce:transition-none"></span>
<span class="kbd07-dark:hidden">Light</span><span class="hidden kbd07-dark:inline">Dark</span><span class="sr-only"> theme</span>
</label>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Arrow Keys and Navigation Key Layout
Source: https://codefronts.com/snippets/tailwind-css-kbd-keys/tailwind-arrow-keys-navigation-key-layout/
The inverted-T arrow cluster and the six-key navigation block, laid out on explicit grid tracks so the shape survives every viewport. One [--u:clamp(…)] unit sizes every cap through size-(--u), and each arrow glyph is aria-hidden with a spoken name beside it.
## HTML
```html
<section class="kbd-07 relative w-full min-h-svh scheme-light kbd07-dark:scheme-dark bg-kbd07-bg text-kbd07-ink font-kbd07-sans" aria-label="Arrow keys and navigation glyphs demo">
<div class="grid min-h-svh place-items-center px-5 pt-20 pb-12">
<div class="grid w-full min-w-0 max-w-[46rem] gap-4 sm:grid-cols-2">
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Arrow cluster</h2>
<div class="grid grid-cols-[repeat(3,var(--u))] gap-1.5 [--u:clamp(44px,12vw,56px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-1 size-(--u) text-xl"><span aria-hidden="true">↑</span><span class="sr-only">Arrow up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-1 row-start-2 size-(--u) text-xl"><span aria-hidden="true">←</span><span class="sr-only">Arrow left</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-2 row-start-2 size-(--u) text-xl"><span aria-hidden="true">↓</span><span class="sr-only">Arrow down</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] col-start-3 row-start-2 size-(--u) text-xl"><span aria-hidden="true">→</span><span class="sr-only">Arrow right</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Explicit grid tracks — the inverted T survives every viewport.</p>
</section>
<section class="grid min-w-0 content-start justify-items-center gap-5 rounded-2xl border border-kbd07-rule bg-kbd07-panel p-6 sm:p-7">
<h2 class="justify-self-start text-[11px] font-semibold uppercase tracking-[0.2em] text-kbd07-acc">Navigation</h2>
<div class="grid w-full max-w-[15rem] grid-cols-3 gap-1.5 [--u:clamp(44px,12vw,52px)]">
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Insert</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Home</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↑</span><span class="sr-only">up</span></kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Delete</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">End</kbd>
<kbd class="grid place-items-center rounded-[10px] border border-kbd07-rim bg-linear-to-b from-kbd07-top to-kbd07-cap font-kbd07-sans font-semibold text-kbd07-capink shadow-[0_2px_0_var(--color-kbd07-edge),0_6px_12px_-6px_var(--color-kbd07-shade)] h-(--u) min-w-0 px-2 text-[13px] leading-tight">Page <span aria-hidden="true">↓</span><span class="sr-only">down</span></kbd>
</div>
<p class="justify-self-start text-[13px] leading-snug text-kbd07-mut">Word labels get their own grid, in the order they sit on a full-size board.</p>
</section>
</div>
</div>
<div class="absolute top-3.5 right-4 z-10">
<input id="kbd-07-theme" type="checkbox" class="peer sr-only">
<label for="kbd-07-theme" class="inline-flex min-h-11 cursor-pointer select-none items-center gap-2.5 rounded-full border border-current/55 px-4 font-sans text-[11px] font-bold uppercase leading-none tracking-[0.16em] text-kbd07-ink transition-colors hover:border-current peer-focus-visible:outline-3 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-kbd07-acc">
<span aria-hidden="true" class="size-3 flex-none rounded-full bg-current transition-[background-color,box-shadow] duration-300 kbd07-dark:bg-transparent kbd07-dark:shadow-[inset_-4px_-2px_0_0_currentColor] motion-reduce:transition-none"></span>
<span class="kbd07-dark:hidden">Light</span><span class="hidden kbd07-dark:inline">Dark</span><span class="sr-only"> theme</span>
</label>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
/* Theme state: follows the OS; the corner switch flips it for THIS demo only. */
@custom-variant kbd07-dark {
@media (prefers-color-scheme: dark) {
&:where(.kbd-07:not(:has(#kbd-07-theme:checked)), .kbd-07:not(:has(#kbd-07-theme:checked)) *) {
@slot;
}
}
@media (prefers-color-scheme: light) {
&:where(.kbd-07:has(#kbd-07-theme:checked), .kbd-07:has(#kbd-07-theme:checked) *) {
@slot;
}
}
}
/* Every colour is light-dark(day, night): the root's scheme-light / scheme-dark utility picks the side. */
@theme {
--color-kbd07-bg: light-dark(#edf3f0, #0d1412);
--color-kbd07-bg: light-dark(oklch(0.959 0.007 164.9), oklch(0.183 0.011 175.6));
--color-kbd07-panel: light-dark(#ffffff, #141d1a);
--color-kbd07-panel: light-dark(oklch(1 0 0), oklch(0.221 0.014 172.5));
--color-kbd07-shade: light-dark(#0d2a2033, #00000099);
--color-kbd07-shade: light-dark(oklch(0.259 0.04 167.8 / 0.2), oklch(0 0 0 / 0.6));
--color-kbd07-ink: light-dark(#13201c, #e3eeea);
--color-kbd07-ink: light-dark(oklch(0.23 0.02 173.3), oklch(0.94 0.013 172.4));
--color-kbd07-mut: light-dark(#4f615b, #94a9a1);
--color-kbd07-mut: light-dark(oklch(0.476 0.024 173), oklch(0.716 0.026 170.6));
--color-kbd07-rule: light-dark(#dce6e1, #22302b);
--color-kbd07-rule: light-dark(oklch(0.916 0.013 164.8), oklch(0.295 0.021 170.9));
--color-kbd07-cap: light-dark(#f6faf8, #1d2925);
--color-kbd07-cap: light-dark(oklch(0.982 0.005 165), oklch(0.268 0.018 172.4));
--color-kbd07-top: light-dark(#ffffff, #26342f);
--color-kbd07-top: light-dark(oklch(1 0 0), oklch(0.311 0.021 171));
--color-kbd07-rim: light-dark(#c3d2cc, #34453f);
--color-kbd07-rim: light-dark(oklch(0.851 0.018 170), oklch(0.374 0.024 171.4));
--color-kbd07-edge: light-dark(#a6b8b1, #040706);
--color-kbd07-edge: light-dark(oklch(0.767 0.022 170.4), oklch(0.123 0.008 174.7));
--color-kbd07-capink: light-dark(#17241f, #e2ede9);
--color-kbd07-capink: light-dark(oklch(0.246 0.02 168.8), oklch(0.937 0.013 172.4));
--color-kbd07-acc: light-dark(#0b7a5d, #4fd1a8);
--color-kbd07-acc: light-dark(oklch(0.516 0.101 168.4), oklch(0.778 0.129 168.7));
--font-kbd07-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as utilities so the stage is sized before the browser build compiles. */
.kbd-07 {
width: 100%;
min-height: 100svh;
position: relative;
}
```How this works
Place, don't flow. A flex row of four arrows breaks into a line at narrow widths. Grid placement pins each cap:
<div class="grid grid-cols-[repeat(3,var(--u))] gap-1.5 [--u:clamp(44px,12vw,56px)]">
<kbd class="col-start-2 row-start-1 size-(--u)">↑</kbd>
<kbd class="col-start-1 row-start-2 size-(--u)">←</kbd> …v4 shorthand. size-(--u) is Tailwind v4's spelling of size-[var(--u)].
Make it yours
- Smaller clusters for inline help:
[--u:32px]andtext-sm. - Highlight the key being described:
border-kbd07-acc text-kbd07-acc. - WASD: reuse the grid with letters.
Gotchas — read before shipping
size-(--u)requires v4; in v3 writew-[var(--u)] h-[var(--u)].- Arrow glyphs vary by font; Space Grotesk's are balanced, system fonts may not be.
- The arbitrary property sets
--uon the grid, so every cap inside inherits the same unit.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 123+ | 17.5+ | 128+ | 123+ |
Tailwind v4's own sheet needs Chrome 111 / Safari 16.4 / Firefox 128 (cascade layers, @property, color-mix()); the light-dark() theme tokens raise the floor to Chrome 123 / Safari 17.5.