Style
elements man style Read as markdownThe Elements design system, shipped as @elements/style. A set of CSS files
that give an Elements app a complete look: semantic design tokens layered over
OKLCH color ramps, bare HTML elements that style themselves, a small family of
component classes, atomic utilities, dark mode, and a monochrome default that
brands with a single accent override.
@elements/style is CSS only. There is no JavaScript in this package.
Nothing to import into a .ts file, no runtime, no build step of its own. You
import CSS and write HTML with classes. Interactive widgets that need
JavaScript (dialogs, dropdowns, toasts, menus, command palettes, comboboxes,
calendars, data tables, sheets, and so on) live in a separate @elements/ui
package that is not shipped in v1. Everything documented here is styling you
get from importing CSS and applying classes.
This page is the quick reference. Every section links to a chapter that covers it in full.
Getting Started
A scaffolded app is already wired: app/shared/styles/page.css imports the
package and every page's style.css imports that baseline. In an existing app,
install and import it once:
elements install @elements/style
@import "@elements/style";
That one import loads the tokens, the reset, base element styling, typography, and every component and utility. From there you write HTML:
<main class="page-shell">
<div class="stack is-lg">
<h1>Account</h1>
<p class="lede">Manage your profile and billing.</p>
<div class="card">
<div class="card-head"><h3>Profile</h3></div>
<div class="card-body">
<form class="is-grid">
<div class="field"><label>First name</label><input></div>
<div class="field"><label>Last name</label><input></div>
<div class="field is-full">
<label>Email</label>
<input type="email">
<p class="hint">We'll never share it.</p>
</div>
</form>
</div>
<div class="card-foot">
<button class="is-ghost">Cancel</button>
<button class="is-primary">Save</button>
</div>
</div>
</div>
</main>
See install for the subpath export map and how a scaffolded app is wired.
The Naming Rule
One rule runs through every class name in the system:
Bare nouns are things.
is-adjectives are how they're rendered.
-
Elements and components are bare nouns, the thing itself:
<button>,<input>,.card,.callout,.pill,.field,.tab,.terminal. -
Component parts carry the family prefix, a part named after its parent:
.card-head,.card-body,.callout-title,.pill-dot,.tab-list,.tab-panel. -
Modifiers and state use
is-, an adjective describing how the noun renders, meaning the same thing everywhere:is-primary,is-ghost,is-danger,is-sm,is-lg,is-block,is-active,is-error,is-ok,is-loading,is-disabled. -
Atomic utilities are axis-prefixed and never take
is-:.text-sm,.bg-soft,.font-mono,.gap-4,.hidden.
Each is- modifier owns one axis, so they combine freely and order never
matters:
<button class="is-primary is-lg is-block">Sign up</button>
<input class="is-sm is-error">
<div class="callout is-warning">Heads up</div>