v0.6.4
Go to GitHub repository

Styling & Theming

Le-Kit is designed to be style-agnostic at its core. All visual decisions — colors, spacing, radii, typography — flow through CSS custom properties, so they can be overridden globally, per-theme, or per-element without touching the component source.

Design tokens

The library ships two CSS layers that you import together:

  • base.css — structural tokens: spacing scale, typography, border radii, transitions, and z-index layers. These rarely differ between themes.
  • theme file — color tokens for a specific look: default.css, dark.css, warm.css, and so on.
Minimal import
@import 'le-kit/dist/themes/base.css';
@import 'le-kit/dist/themes/default.css';

Setting a theme on the <html> element activates it for every component on the page. You can also scope a theme to any subtree:

<!-- whole page uses dark theme -->
<html theme="dark">

<!-- or just a section -->
<section theme="dark">
  <le-card>...</le-card>
</section>

Per-component CSS variables

Each component exposes its own set of custom properties that fall back to the global tokens. For example, <le-button> uses:

:host {
  --le-button-border-radius: var(--le-radius-md);
  --le-button-padding-x:     var(--le-spacing-3);
  --le-button-padding-y:     var(--le-spacing-1);
  --le-button-font-size:     var(--le-font-size-md);
  --le-button-color:         var(--le-color-primary-contrast);
  /* … */
}

You can override any of these from the outside — either globally or scoped to a specific context — without breaking the fallback chain:

/* Round every button */
le-button {
  --le-button-border-radius: var(--le-radius-full);
}

/* Override only inside a specific component */
.hero le-button {
  --le-button-font-size: var(--le-font-size-lg);
}

CSS parts

For cases where custom properties are not enough, components expose internal elements via the ::part() pseudo-element, giving you direct access to shadow DOM nodes from the outside.

/* Style the inner container of le-string-input */
le-string-input::part(container) {
  border-style: dashed;
}

Available parts for each component are listed on their individual documentation pages.

Open design question

The right strategy for the variable system is still an open question and an active area of thought for the project. There are two main approaches, each with real trade-offs:

Option A — per-component variables

Every fine-grained value gets its own prefixed variable. Themes set them all explicitly.

:root {
  --le-border-color:        #999;
  --le-button-border-color: #333;
  --le-input-border-color:  #666;
  /* one variable per component per property */
}

Pros: maximum control; you can tune anything without side-effects.
Cons: lots of variables to maintain; easy for themes to drift visually because nothing enforces consistency.

Option B — shared variables, locally reassigned

A small set of semantic tokens is used everywhere. To diverge, you reassign the shared token for a specific scope.

:root {
  --le-border-color: #999;
}

/* Make buttons use a stronger border, keeping other components intact */
le-button {
  --le-border-color: #333;
}

Pros: fewer variables; design consistency is easier to enforce because components share tokens by default.
Cons: reassigning a shared token in a wide scope can cause unexpected visual changes in nested components.

Current approach

Le-Kit currently uses a hybrid: global semantic tokens in base.css and the theme files, with component-local variables that fall back to those tokens. This means you can override at whichever level makes sense. The right balance — how many levels, how granular, how much fallback chaining — is still being worked out, and feedback from real use cases is welcome.

Creating a custom theme

Copy any of the existing theme files and change the selector. You only need to redeclare the tokens you want to change — the rest falls through to the base.

my-theme.css
/* Import base tokens first */
@import 'le-kit/dist/themes/base.css';

[theme="my-theme"] {
  --le-color-primary:          #7c3aed;
  --le-color-primary-light:    #a78bfa;
  --le-color-primary-dark:     #5b21b6;
  --le-color-primary-contrast: #ffffff;

  /* override only what you need */
}
<html theme="my-theme">
  <!-- every le-kit component now uses your colors -->
</html>