Usage

husk is a CSS file that styles semantic HTML elements directly. No classes, no JavaScript framework, no build step. Write standard HTML and it looks good.

Installation

CDN (fastest)

Add one line to your HTML:

<link rel="stylesheet" href="https://unpkg.com/husk-ui@latest/dist/husk.css">

npm

npm install husk-ui

Then import it:

/* In your CSS */
@import "husk-ui/css";

/* Or link it in HTML */
<link rel="stylesheet" href="node_modules/husk-ui/dist/husk.css">

Download

Download dist/husk.css and drop it into your project. That's it.

Starter template

Copy this and you're ready to go:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/husk-ui@latest/dist/husk.css">
    <title>My App</title>
</head>
<body>
    <nav>
        <strong>My App</strong>
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
        </ul>
    </nav>
    <main>
        <h1>Hello, world</h1>
        <p>This already looks good.</p>
        <button>Click me</button>
    </main>
</body>
</html>

JavaScript (optional)

husk is CSS-first. All layouts and components work without JavaScript. The optional JS file (~1.4 KB gzipped) adds two features:

  • Toast notificationsHusk.toast(message, options)
  • Dialog wiring — auto-connects data-open and data-close buttons to <dialog> elements
<!-- Add before </body> -->
<script src="https://unpkg.com/husk-ui@latest/dist/husk.js"></script>

Toast API

// Basic
Husk.toast("Something happened");

// With type
Husk.toast("Saved!", { type: "success" });

// Types: "success" | "danger" | "warning" | "info"

// Custom duration (ms), default is 3000
Husk.toast("Heads up", { type: "warning", duration: 5000 });

// Manual dismiss (duration: 0)
const t = Husk.toast("Loading...", { duration: 0 });
t.dismiss(); // close it later

Dialog wiring

Add data-open="dialog-id" to any button to open a dialog, and data-close inside the dialog to close it. Clicking the backdrop also closes it.

<button data-open="confirm">Delete</button>

<dialog id="confirm">
    <h3>Delete this item?</h3>
    <p>This cannot be undone.</p>
    <menu>
        <button data-close>Cancel</button>
        <button data-close data-variant="danger">Delete</button>
    </menu>
</dialog>

If you add dialogs dynamically, call Husk.dialog.init() to re-wire them.

Modular imports

Don't need everything? Import just what you use:

<!-- Foundation (required) -->
<link rel="stylesheet" href="husk-ui/src/base.css">

<!-- Pick what you need -->
<link rel="stylesheet" href="husk-ui/src/typography.css">
<link rel="stylesheet" href="husk-ui/src/forms.css">
<link rel="stylesheet" href="husk-ui/src/tables.css">

<!-- Individual components -->
<link rel="stylesheet" href="husk-ui/src/components/card.css">
<link rel="stylesheet" href="husk-ui/src/components/dialog.css">
<link rel="stylesheet" href="husk-ui/src/components/badge.css">
<link rel="stylesheet" href="husk-ui/src/components/tooltip.css">
<!-- ... and so on -->

Available component files:

File What it styles
base.css Reset, design tokens, document defaults
typography.css Headings, paragraphs, links, lists, code, blockquotes
forms.css Inputs, buttons, selects, checkboxes, radios
tables.css Tables with hover states
components/card.css <article> cards and grid
components/dialog.css <dialog> modals
components/details.css Accordions and dropdowns
components/nav.css Navigation bars
components/toast.css Toast notification styling
components/badge.css <mark> badges
components/progress.css Progress bars and meters
components/tooltip.css Hover tooltips
components/alert.css Alert callouts
components/switch.css Toggle switches
components/skeleton.css Loading skeletons
components/sidebar.css Sidebar layouts
components/spinner.css Loading spinners
components/breadcrumb.css Breadcrumb navigation

Browser support

husk uses standard CSS and HTML. It works in all modern browsers:

  • Chrome / Edge 88+
  • Firefox 78+
  • Safari 14+

No polyfills required. Native <dialog>, :has(), and color-scheme are used where supported with graceful fallbacks.