Skip to content

Button

A native <button> element styled via class + data attributes from the optional styles layer. Six variants, four sizes, color theming, high-contrast and disabled states β€” all driven by data attributes on a single .x-button class.

Install

import "elements-kit/ui/styles/theme.css";
import "elements-kit/ui/styles/scaling.css";
import "elements-kit/ui/styles/radius.css";
import "elements-kit/ui/styles/space.css";
import "elements-kit/ui/styles/shadow.css";
import "elements-kit/ui/styles/typography.css";
import "elements-kit/ui/styles/cursor.css";
import "elements-kit/ui/styles/unset.css";
// import any color scales you want to use for color theming:
import "elements-kit/ui/styles/palette/mint.css";
import "elements-kit/ui/styles/accent/mint.css";
// import any gray scales you want to use for neutral theming:
import "elements-kit/ui/styles/palette/slate.css";
import "elements-kit/ui/styles/neutral/slate.css";
// and of course the button itself:
import "elements-kit/ui/button/button.css";

See Styles for the full token system, accent/gray scale lists, and theming knobs.

API

<button
class="unset x-button"
data-variant="solid"
data-size="2"
data-accent="mint"
>
Click me
</button>

The unset class (Styles β†’ Unset native styles) clears the browser’s default <button> rendering so .x-button styles render predictably. Skip it and you’ll see leaked native styling (gray background, system font, beveled border).

AttributeValues
data-variantsolid, soft, surface, outline, text, borderless
data-size1, 2, 3, 4
data-accentany imported color scale (mint, blue, iris, …)
data-iconmodifier β€” square shape sized by height. Use for icon-only buttons.
data-high-contrastmodifier β€” boosts contrast against the page background
data-loadingmodifier β€” sets position: relative for a spinner overlay
disabled / data-disablednative :disabled state, or data-disabled on non-button elements

Sizing

Each size maps to a height token from the space scale:

data-sizeheightradius
1--space-5 (24px)max(--radius-1, --radius-pill)
2--space-6 (32px)max(--radius-2, --radius-pill)
3--space-7 (40px)max(--radius-3, --radius-pill)
4--space-8 (48px)max(--radius-4, --radius-pill)

The radius respects data-radius on a parent β€” set data-radius="pill" on the page root for pill buttons everywhere.

Variants

  • solid β€” flat, color-driven fill. Confident primary action.
  • soft β€” tinted, low-emphasis background. Pairs well with surfaces.
  • surface β€” outlined panel with subtle fill. Borderline calls-to-action.
  • outline β€” bordered, transparent fill. Tertiary actions.
  • text β€” no background, no border, and uses negative margins so the button sits flush with surrounding body copy. Use for inline calls-to-action inside paragraphs.
  • borderless β€” no background, no border, no margin trick. Standalone button without chrome. Toolbar-style.

Icon button

Add data-icon to make the button a square sized by height β€” for icon-only buttons (toolbar actions, close, etc.). Works with every variant and every size.

<button class="unset x-button" data-variant="soft" data-size="2" data-icon aria-label="Close">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" fill="none" />
</svg>
</button>
SizeShape
124Γ—24
232Γ—32
340Γ—40
448Γ—48

For data-variant="text" icon buttons, the kit swaps the asymmetric padding for uniform square padding (4 / 6 / 8 / 12px per size) so the icon sits centered. The negative-margin trick still applies β€” the button inlines flush with surrounding text.

.x-button is class-only β€” apply it to any element you want shaped like a button. The most common case is a link that should look like a button:

<a
class="unset x-button"
data-variant="solid"
data-size="2"
href="/getting-started/installation"
>
Get started
</a>

unset zeroes the anchor’s default underline and color so the .x-button styles render exactly like on a <button>. Native semantics (focus, navigation, right-click β†’ open in new tab) are preserved β€” pick <a> when the action navigates and <button> when it triggers a JS handler.

Radius

Set data-radius="<value>" on a parent (e.g. <body>) to control corner radius for every button beneath. Values follow Styles β†’ Radius:

<div data-radius="pill">
<button class="unset x-button" data-variant="solid">Pill</button>
</div>
<div data-radius="none">
<button class="unset x-button" data-variant="solid">Square</button>
</div>
data-radiusEffect
nonesquare corners β€” --radius-factor: 0
smalltighter β€” --radius-factor: 0.75
mediumdefault
largesofter β€” --radius-factor: 1.5
pillfully rounded β€” --radius-pill: 9999px

The size’s own radius is max(--radius-N, --radius-pill), so data-radius="pill" always wins regardless of size.

Theming

Switch the color on a single button with data-accent="<color>", or set it on any ancestor (e.g. <body>) to theme the whole subtree.

<body data-accent="iris" data-radius="large">
<button class="unset x-button" data-variant="solid" data-size="3">
Themed primary
</button>
</body>

Light/dark flips automatically via the .dark class on a parent β€” see Light & dark.