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).
| Attribute | Values |
|---|---|
data-variant | solid, soft, surface, outline, text, borderless |
data-size | 1, 2, 3, 4 |
data-accent | any imported color scale (mint, blue, iris, β¦) |
data-icon | modifier β square shape sized by height. Use for icon-only buttons. |
data-high-contrast | modifier β boosts contrast against the page background |
data-loading | modifier β sets position: relative for a spinner overlay |
disabled / data-disabled | native :disabled state, or data-disabled on non-button elements |
Sizing
Each size maps to a height token from the space scale:
data-size | height | radius |
|---|---|---|
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>| Size | Shape |
|---|---|
1 | 24Γ24 |
2 | 32Γ32 |
3 | 40Γ40 |
4 | 48Γ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.
Use as a link
.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-radius | Effect |
|---|---|
none | square corners β --radius-factor: 0 |
small | tighter β --radius-factor: 0.75 |
medium | default |
large | softer β --radius-factor: 1.5 |
pill | fully 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.