Skip to content

an HTML-first
design system.

Native HTML. Modern CSS. Progressive custom elements by default, Shadow DOM when it pays off. Rename the l- prefix to ship a design system that bears your name.

v0.1.0// public preview

What is Luxen UI?

Luxen UI is an HTML & CSS-first UI library that styles native HTML elements or extends HTML with Progressive Custom Elements (<l-*>). Light DOM first, Shadow DOM only when needed.

Elements in bold are styled or extended by Luxen.

<a><abbr><address><area><article><aside><audio><b><base><bdi><bdo><blockquote><body><br><button><canvas><caption><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><div><dl><dt><em><embed><fieldset><figcaption><figure><footer><form><h1><h6><head><header><hgroup><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><math><menu><meta><meter><nav><noscript><object><ol><optgroup><option><output><p><picture><portal><pre><progress><q><rp><rt><ruby><s><samp><script><search><section><select><slot><small><source><span><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><u><ul><var><video><wbr> · <l-avatar><l-badge><l-carousel><l-carousel-item><l-dialog><l-divider><l-icon><l-dropdown><l-dropdown-item><l-input-otp><l-input-stepper><l-popover><l-rating><l-skeleton><l-spinner><l-tabs><l-toast><l-tooltip><l-tree><l-tree-item>

Luxen elements come in four flavors: ⏣ Native HTML Elements are standard HTML elements styled purely with CSS, no JavaScript needed. ⬡ Progressive Custom HTML Elements wrap a native element like <input> or <button> to upgrade it with richer behavior while keeping the underlying HTML usable without JavaScript. ◇ Custom HTML Elements (no Shadow DOM) are new tags declared in HTML that live in the light DOM without wrapping any native element. ⬢ Custom HTML Elements with Shadow DOM encapsulate their rendering for UI patterns where server-side rendering is not required.

html
<button
  id="edit-btn"
  class="l-button"
>
  Edit
</button>

<l-popover for="edit-btn">
  <p>Popover content here.</p>
</l-popover>
html
<details
  class="l-disclosure"
  data-variant="bordered"
  data-marker="arrow"
>
  <summary>Toggle</summary>
  <div>Content</div>
</details>
html
<l-input-stepper>
  <input
    type="number"
    min="0"
    max="10"
    value="5"
  />
</l-input-stepper>
html
<button
  type="button"
  aria-label="Close"
  class="l-close"
  data-appearance="ring"
  command="close"
  commandfor="target-identifier"
></button>