20 CSS Kbd Keys
20 hand-coded CSS keyboard keys for documentation, shortcut cheatsheets, settings panels, command hints and onboarding. Covers the inline kbd element in running prose, 3D caps that genuinely depress, multi-key combos with the separator outside the keys, Mac glyphs against Windows words, arrow clusters, non-uniform widths for Space and Enter, and the reading surfaces a shortcut appears in. Scoped under .kbd-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.
Related20 CSS Code Blocks36 CSS Search Bars21 CSS Tooltips30 CSS Badges20 Tailwind CSS Kbd Keys
Course pickPartner: Zero to Mastery
Affiliate linkWant to build production-ready CSS layouts, animations and UI from scratch?
You just browsed 20 keyboard keys. Learn the Flexbox, Grid and animation thinking behind them, so the next component starts in your head, not in a copy-paste.
Every ZTM course in one membership: $25/month, paid yearly at $299 · 30‑day money-back guarantee
The CSS Bootcamp. We may earn a commission, at no extra cost to you.
02. 3D Keycap with Active Push Down (opens in a new tab)
03. Key Combo Layout with Plus Separators (opens in a new tab)
04. Flat Minimalist Keycap for Body Text (opens in a new tab)
05. Fluid Kbd Sizing with Em Units (opens in a new tab)
06. Mac Command vs Windows Ctrl Toggle (opens in a new tab)
07. Arrow Keys and Navigation Glyphs (opens in a new tab)
08. Auto OS Detect Cmd or Ctrl Display (opens in a new tab)
09. Function Keys and Wide Space Bar Caps (opens in a new tab)
10. Icon Only Keys with Inline SVG (opens in a new tab)
11. Search Bar Shortcut Hint with Kbd (opens in a new tab)
12. Keyboard Shortcut Cheatsheet Grid (opens in a new tab)
13. Tooltip with Kbd Shortcut Hint (opens in a new tab)
14. App Settings Shortcut Mapping Table (opens in a new tab)
15. Live Key Press Feedback Display (opens in a new tab)
16. Neumorphic Soft UI Keycap (opens in a new tab)
17. Glassmorphic Translucent Keycap (opens in a new tab)
18. Retro Typewriter Round Keycap (opens in a new tab)
19. Terminal Monospace Kbd Key (opens in a new tab)
20. Dark Mode Kbd Keys with CSS Variables (opens in a new tab)
Frequently asked questions
How do I style the kbd tag in CSS?
<kbd> element ships with a browser default of monospace text and nothing else, so every keycap you have seen is author CSS. The recipe is short: a small inline-block with padding, a border, a background one step off the page surface, and a rounded corner. What separates a good cap from a bad one is the depth cue — a single box-shadow: 0 1px 0 in a darker tone reads as the key's side wall and does more work than any gradient. Two details are worth getting right immediately. Size the cap in em rather than px so it scales with whatever text it sits in; a key hardcoded to 12px looks broken inside a heading. And set line-height: 1 on the cap, because the inherited body line-height will otherwise make it taller than the text around it and push the line box open. Keep the label at 11px or above at the smallest — a key rendered smaller than that fails both legibility and contrast.How do I mark up a keyboard shortcut like Ctrl + C?
<kbd> per physical key and put the separator BETWEEN them, never inside: <kbd>Ctrl</kbd> + <kbd>C</kbd>. This matters for more than tidiness. A screen reader announcing a single key element containing the string "Ctrl+C" reads the punctuation as part of the key, whereas separate elements with the plus outside are announced as a combination. The HTML spec does allow nesting — a <kbd> wrapping several child <kbd> elements represents one composite input — and that is the most semantically precise form if you want it. For a sequential shortcut, where the user presses one key and then another rather than holding both, use the word "then" instead of a plus. That distinction is invisible in a screenshot but it is the difference between a working instruction and a confusing one, and almost no documentation gets it right.Should keyboard keys be sized in px or em?
em, in almost every case. A keycap is inline content that sits inside running text, so its job is to match the type around it — and em resolves against the element's own font-size, which means one set of rules works in body copy, in a heading, and in a small caption without a single override. Express the padding, the border-radius and the minimum width in em too, or you get a cap whose text scales while its box does not. The exception is the border. A hairline is a visual constant rather than a typographic measure, so border-width belongs in px: a 1px key outline should stay 1px whether the surrounding text is 12px or 32px. The same reasoning applies to the depth shadow's offset. This is the single most common mistake in keycap CSS — everything scales except the two things that should not.How do I show Mac and Windows shortcuts on the same page?
:has() on the container does it with no JavaScript at all: check the Windows radio and every Mac glyph inside the container swaps to its Windows word through attribute-driven display rules. If you want the page to be correct on arrival, detect the platform once and set a data-os attribute on a wrapper, then let attribute selectors style every key from that single value. Feature-detect with navigator.userAgentData?.platform and fall back to navigator.platform, which is deprecated but still the only thing some browsers report. One caution worth stating plainly: user-agent sniffing is acceptable here because the consequence of getting it wrong is a cosmetically wrong label, not a broken or insecure page. Never make a capability or security decision the same way — and always give the reader a manual override, since plenty of people use a Mac keyboard on Windows and the reverse.How do I make icon-only keys accessible?
aria-hidden="true" and put visually-hidden text inside the key carrying the real label — "Escape", "Backspace", "Search". Use the clip-path visually-hidden pattern rather than display: none or visibility: hidden, because both of those remove the text from the accessibility tree entirely, which is precisely what you were trying to avoid. Two more points apply to any key that is also a control. If the cap is interactive it needs a genuine 44x44px target per WCAG 2.5.8, which usually means padding the hit area rather than growing the glyph. And it needs a visible :focus-visible ring at 3:1 contrast against its surroundings. A purely decorative cap — a specimen in documentation — is not interactive and should not be a button at all; a <kbd> is a label, not a control.How do I lay out an arrow key cluster in CSS?
currentColor for free, and they scale with the cap. The navigation cluster — Home, End, Page Up, Page Down — is the same idea in a two-by-two grid. The one thing to watch on narrow screens is that a fixed-column grid cannot wrap, so the cluster must scale down through its font-size rather than reflow, or it will push the page sideways at 320px.Why does my keycap look wrong inside a heading or a table?
font-size: 12px and padding: 4px is correct in body copy and comically small in a 32px heading. Size in em and the problem disappears. Second, inherited line-height: a cap that does not set line-height: 1 inherits the paragraph's 1.6, which makes the key box taller than the text and visibly opens up the line it sits on. Third, and specific to tables, is width. A shortcut column holding combinations like <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> has a large minimum content width, so the table refuses to shrink below it and pushes the page sideways on mobile. The fix is not to shrink the keys — it is to wrap the table in a container with overflow-x: auto and let it scroll, because a shortcut table is tabular data and squeezing it destroys the alignment that makes it readable.How do these port to React, Vue, Svelte and Tailwind?
.kbd-NN selector and custom property is framework-agnostic, and the eighteen pure-CSS demos need no JavaScript in any framework. Where behaviour exists the shape is small. Platform detection belongs in an effect rather than the component body: navigator does not exist during a server render in Next or Nuxt, so reading it at module scope throws at build time. Set the data-os attribute inside useEffect, or accept a brief first paint with the default glyphs. The live key-press demo attaches a keydown listener to the document, so in React it belongs in an effect with the removal returned as cleanup — otherwise a remount stacks listeners and every keystroke renders several caps. Vue uses onMounted with onBeforeUnmount; Svelte returns the teardown from onMount. For Tailwind, the cap is a short utility chain and the theme swap maps to dark: variants, though the :has() toggle here needs no variant at all.Related collections
30 CSS Badges
30 hand-coded CSS badges for status indicators, notifications, membership tiers, live-data displays, and SEO / DevOps / financial dashboards — upload progress, typing indicator, transit line status, Core Web Vitals, ECG heartbeat, CI/CD build pipeline, countdown ring, live price ticker, keycap shortcut, wax seal, conference lanyard, and holographic collectibles. Copy-paste HTML and CSS, WCAG 2.2 accessible, MIT licensed.
20 CSS Banners & Alerts
20 hand-coded CSS banner and alert bars for e-commerce storefronts, SaaS dashboards, marketing sites, and compliance-bound products. Covers GDPR cookie consent with a real preferences panel, promo bars with countdown timers, free-shipping threshold progress, app-install smart banners, maintenance and incident status bars, newsletter signup bars, age verification gates, limited-stock urgency banners, live event announcements, browser upgrade notices, geo and currency switchers, sticky top announcement bars, bottom cookie bars, inline form validation alerts, icon-aligned alert banners, left-border accent alerts, diagonal stripe promos, full-width hero banners, animated gradient border alerts, and a text-wrapping laboratory that shows five strategies for the unbreakable string that breaks more banners than anything else. Every bar is scoped under a .ba-NN prefix for no-collision pasting, guards prefers-reduced-motion, carries the correct aria-live and role semantics, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
25 CSS Blockquotes
25 CSS blockquotes for article pull quotes, testimonial cards, docs callout admonitions, statement banners, and social-post embeds. Covers giant decorative quotation marks, minimalist hairline and classic left borders, animated gradient and glowing neon borders, glassmorphism and aurora backgrounds, brutalist cards, speech bubbles, thick accent rails, highlighted mark text, newspaper multi-column layouts, an expandable read-more disclosure, a scroll-snap testimonial slider, and one-click copy.


















