Button

Tag-and-class component. The framework styles bare <button> and any element with the .button class identically. Variants use the .is-* modifier scheme shared with Card.

Live

Combinations

<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
<button class="button">Default</button>
<button class="button is-primary">Primary</button>
<button class="button is-success">Success</button>
<button class="button is-warning">Warning</button>
<button class="button is-danger">Danger</button>
</div>
@use '@adnap/krysalicss' with (
  $feature-list: ('base-reset', 'base-global', 'element-button')
);
Playground

Modifiers

<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
<button class="button is-primary">Primary</button>
<button class="button is-primary is-inverted">Primary inverted</button>
<button class="button is-primary is-outlined">Primary outlined</button>
</div>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem;">
<button class="button is-danger">Danger</button>
<button class="button is-danger is-inverted">Danger inverted</button>
<button class="button is-danger is-outlined">Danger outlined</button>
</div>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem;">
<button class="button is-link">Link</button>
<button class="button is-link" disabled>Link disabled</button>
</div>
@use '@adnap/krysalicss' with (
  $feature-list: ('base-reset', 'base-global', 'element-button')
);
Playground

Variables

VariableDefaultNotes
$selector'button, .button'Re-scope to '.app .btn' for non-intrusive use.
$padding-y0.625remVertical padding. Sized so rendered button height clears WCAG 2.5.5 AAA (44 px).
$padding-x$size-normalHorizontal padding.
$min-width2.75rem (44 px)WCAG 2.5.5 AAA touch-target floor on the horizontal axis. Override to 0 for inline dense toolbars; you accept the AA 24 × 24 px floor.
$border-radius$global-border-radius (5px)Set to 999px for pills.
$inverted-selector'.is-inverted'Reverses (bg, fg) on hover.
$outlined-selector'.is-outlined'Transparent background, themed border + foreground.
$link-selector'.is-link'Renders the button as a link surface: transparent background + border, --kc-link text, --kc-link-hover on hover.
$disabled-opacity$global-disabled-opacity (0.6)Faded opacity applied to :disabled, paired with cursor: not-allowed.
$focus-outline-width$global-focus-outline-width (2px)Width of the :focus-visible outline; clears WCAG 2.4.11.
$focus-outline-style$global-focus-outline-style (solid)Stroke style of the focus outline.
$focus-outline-offset$global-focus-outline-offset (2px)Gap between the button border and the focus ring.
$hover-brightness$global-hover-brightness (0.95)filter: brightness() factor applied on hover; tuned to preserve AA contrast across shipped combinations.

See Combinations and light variants for $enable-light, $default-combination, and $controls — cross-cutting plumbing common to every theme-aware component.

Override example

app.scss
// Exhaustive override: every variable the button module exposes.
// Drop the keys you don't need — defaults are inherited from the
// framework globals (`$global-*`) and the default colour combination.
@use '@adnap/krysalicss/element/button' with (
  // Selector contract. Re-scope to avoid styling bare `<button>` (e.g.
  // when embedding the framework inside a host app's chrome).
  $selector: 'button, .button',
  $inverted-selector: '.is-inverted',
  $outlined-selector: '.is-outlined',
  $link-selector: '.is-link',

  // Sizing. Defaults are tuned so rendered height clears WCAG 2.5.5 AAA
  // (44 × 44 px). Shrink `$min-width` to 0 only if you accept the AA
  // 24 × 24 px floor.
  $padding-y: 0.625rem,
  $padding-x: 1rem,
  $min-width: 2.75rem,
  $border-radius: 999px,

  // (background, foreground) tuple applied to a bare `.button` with no
  // `.is-*` modifier. Keep it themed-token-friendly if you author your
  // own theme.
  $default-combination: (#ffffff, #1a1a1a),

  // Focus-ring tuning — must stay visible against every combination
  // your theme ships.
  $focus-outline-width: 2px,
  $focus-outline-style: solid,
  $focus-outline-offset: 2px,

  // Hover scale (`filter: brightness()`) and disabled fade.
  $hover-brightness: 0.92,
  $disabled-opacity: 0.6,
);

Open this override in playground →

Tokens consumed

TokenUsed for
--kc-default-bg / --kc-default-fgPlain .button (no .is-*).
--kc-{label}-bg / --kc-{label}-fgEach combination modifier (primary, warning, danger, success, light).
--kc-link / --kc-link-hover.is-link rest + hover text colour, matching the <a> typography rules.
--kc-focus-ring:focus-visible outline colour. Falls back to --kc-fg then currentColor if a theme omits it.

Touch-target sizing: WCAG 2.5.5 (AAA). Default $padding-y + $min-width ensure every button renders at ≥ 44 × 44 CSS pixels: the AAA floor for pointer-input targets. The AA floor is 24 × 24 px (WCAG 2.5.8); if you ship inline dense toolbars and accept AA, override $min-width to 0 and reduce $padding-y in your @use ... with (...) invocation. Don't shrink globally: the rest of the framework (focus-ring contrast, padding rhythm) is calibrated against the AAA target.

Contrast: .is-inverted. For non-default combinations, the modifier flips the button onto the page surface: --kc-bg as fill, the combination's --kc-<label>-bg as text and border. Contrast then comes down to the chosen combination colour against the theme's page bg — light, mid-luminance combos (.is-warning) will fail WCAG AA on a white page; reserve them for your own surface-colour overrides. .is-default.is-inverted and plain .is-inverted do a true (bg, fg) swap of the default combination tokens (--kc-default-fg becomes the fill, --kc-default-bg becomes the text + border) so they stay visible on either theme.

Contrast: .is-outlined. The outlined modifier paints palette-literal colours (not theme tokens), so the same hex sits on every page background you ship. On the default light theme, .is-primary, .is-warning, .is-danger and .is-success clear WCAG 1.4.3 AA against white. On the default dark theme, those same literals can fall below AA against the near-black page surface — a documented trade-off in favour of predictable cross-theme appearance. If your dark theme needs strict AA outlined buttons, scope a custom .button selector with theme-aware colour overrides.