Quick start
Copy one file. Write HTML. Done.
Every component, live. Each one is styled from semantic HTML — no classes required.
<article> becomes a card. Wrap in [data-cards] for a responsive grid.
Copy one file. Write HTML. Done.
Import everything or just what you need.
<div data-cards>
<article>
<header><h4>Title</h4></header>
<p>Description</p>
<footer>
<button data-size="sm">Action</button>
</footer>
</article>
</div>
Standard form elements — styled automatically.
<label for="name">Name</label>
<input type="text" id="name" placeholder="Enter your name">
<label for="bio">Bio</label>
<textarea id="bio"></textarea>
<label for="role">Role</label>
<select id="role">
<option>Designer</option>
<option>Developer</option>
</select>
<fieldset>
<legend>Preferences</legend>
<label><input type="checkbox"> Option</label>
</fieldset>
Add data-switch to a checkbox.
<label>
<input type="checkbox" data-switch checked> Notifications
</label>
<label>
<input type="checkbox" data-switch disabled> Disabled
</label>
Native <dialog> element. Use data-open and data-close to
wire triggers (requires JS).
<button data-open="my-dialog">Open modal</button>
<dialog id="my-dialog">
<h3>Title</h3>
<p>Content here.</p>
<menu>
<button data-close>Cancel</button>
<button data-close>Confirm</button>
</menu>
</dialog>
Use role="alert" with data-type for Notion-style callout blocks.
husk works with any static site generator.
Your changes are live.
JS is optional. Only needed for toasts and dialog wiring.
v0.2 renames --husk-color to --husk-accent.
<div role="alert" data-type="info">
<div>
<strong>Title</strong>
<p>Description text.</p>
</div>
</div>
<!-- Types: info, success, warning, danger -->
Call Husk.toast(message, options). Requires the JS file.
Husk.toast("Something happened");
Husk.toast("Saved!", { type: "success" });
Husk.toast("Error", { type: "danger", duration: 5000 });
<mark> becomes a badge. Add data-type for color variants.
<mark>Default</mark>
<mark data-type="success">Published</mark>
<mark data-type="warning">Draft</mark>
<mark data-type="danger">Archived</mark>
<mark data-type="info">New</mark>
<mark data-type="neutral">v0.1.0</mark>
Add data-tooltip to any element. Use data-tooltip-pos="bottom" for bottom
placement.
<button data-tooltip="Copy to clipboard">Hover me</button>
<button data-tooltip="Bottom" data-tooltip-pos="bottom">Below</button>
Native <progress> and <meter> elements.
<progress value="72" max="100"></progress>
<meter min="0" max="100" low="20" high="80" optimum="90" value="75"></meter>
Add data-loading to overlay a spinner on any element, or use data-spinner
for a
standalone spinner.
<!-- Standalone spinners -->
<span data-spinner="sm"></span>
<span data-spinner></span>
<span data-spinner="lg"></span>
<!-- Loading overlay on a button -->
<button data-loading>Save</button>
Add data-skeleton to any element for a shimmer loading placeholder.
<div data-skeleton style="width: 3rem; height: 3rem;
border-radius: var(--husk-radius-full);"></div>
<p data-skeleton="text" style="width: 60%; height: 1rem;"></p>
<!-- Shapes: default (rectangle), "circle", "text" -->
<details> / <summary> — Notion-style collapsible toggles.
A CSS library that styles HTML elements directly.
No. JS is optional — only for toasts and dialog helpers.
Override --husk-* custom properties.
<details open>
<summary>Question</summary>
<p>Answer</p>
</details>
Add data-dropdown to <details> for a popover menu.
Standard <table> with clean borders and hover rows.
| Name | Role | Status |
|---|---|---|
| Aryan | Owner | Active |
| Sarah | Editor | Away |
| Mike | Viewer | Offline |
<table>
<thead>
<tr><th>Name</th><th>Status</th></tr>
</thead>
<tbody>
<tr><td>Aryan</td><td>Active</td></tr>
</tbody>
</table>
All text elements are styled out of the box.
Regular text with a link, bold, italic,
inline code, and Ctrl + S keyboard shortcuts.
<a href="#">Link</a>
<strong>Bold</strong>
<code>inline code</code>
<kbd>Ctrl</kbd> + <kbd>S</kbd>
The best CSS framework is the one you don't notice.
Everyone who's been burned by CSS
<blockquote>
<p>Quote text here.</p>
<cite>Attribution</cite>
</blockquote>
function deploy(app) {
return fetch('/api/deploy', {
method: 'POST',
body: JSON.stringify({ app }),
});
}
<pre><code>function deploy(app) {
// your code
}</code></pre>