defuss-shadcn / Introduction / how-to-use
How to Use
Installation put the files on your page - this is how they fit together. Tokens. Component skill. CSS. HTML. JavaScript (if needed). That's the whole system.
/* default-semantic-tokens.css - the design system */:root { --background: oklch(1 0 0); --foreground: oklch(0.145 0.005 285); --primary: oklch(0.205 0.005 285); --primary-foreground: oklch(0.985 0.002 247); --border: oklch(0.88 0.004 247); --radius: 0.625rem; /* ...all color pairs, shadows, spacing */}.dark { /* same keys, dark values */ }# Pattern: Button## Native basis`<button>` element. Also works on `<a>` for link-style buttons.## Native Web APIs- `<button>` - native clickable element with built-in keyboard and form support- `:focus-visible` - keyboard-only focus ring- `commandfor` / `command` - declarative button→dialog/popover triggers without JS # ...prefers-reduced-motion, prefers-contrast, forced-colors## Structure<button class="btn" data-variant="default">Click me</button>## Variants| data-variant | Surface | Text | Hover ||---------------|----------------------|--------------------------|-----------------|| default | --primary | --primary-foreground | opacity: 0.88 || secondary | --secondary | --secondary-foreground | opacity: 0.8 || outline | --background + border | --foreground | --accent bg || ghost | transparent | --foreground | --accent bg || destructive | --destructive | --destructive-foreground | opacity: 0.88 || link | transparent | --primary | underline | # ...sizes, accessibility, notes/* button.css - styled with tokens */@layer components { .btn { display: inline-flex; align-items: center; border-radius: var(--radius-md); font-weight: 500; } .btn[data-variant="default"] { background: var(--primary); color: var(--primary-foreground); } /* ...secondary, destructive, outline, ghost, link */}<button class="btn" data-variant="default" data-dialog-trigger="confirm"> Open Dialog</button><dialog id="confirm" class="dialog"> <div class="dialog-content">...</div></dialog>// dialog.js - wire interactivity through df$ (query + morph, installed by core)function init() { for (const trigger of df$('[data-dialog-trigger]:not([data-init])')) { df$(trigger).attr('data-init', ''); // the double-init guard const dialog = df$(`#${trigger.dataset.dialogTrigger}`).get(0); if (!dialog) continue; df$(trigger).on('click', () => dialog.showModal()); // native protocol stays native } /* ...close-on-backdrop, [data-dialog-close] buttons, focus restore */}init();new MutationObserver(init).observe(document, { childList: true, subtree: true });Where to go next
Configure variants and sizes in markup with the Data Attribute API, drive and observe the interactive components' named states through the State API, and read a component's component skill before writing its HTML.
Comments, ideas or improvements? Edit this page's source on GitHub