Doc Page

Theming

Use semantic theme tokens without coupling behavior logic to visual styles.

Updated: 2026-06-03 · Owner: docs@nake-ui

Headless Styling Contract

The core and adapter packages do not require visual CSS. Styling is a separate layer that reads public DOM attributes and applies product visuals.

This separation lets you use plain CSS, CSS Modules, Tailwind, CSS-in-JS, design tokens, or a generated theme package without changing primitive behavior.

Sources: shared/en/theming

Public Selectors

Prefer selectors based on public attributes:

[data-ui="dialog"][data-slot="content"][data-state="open"] {
  opacity: 1;
}

[data-ui="listbox"] [data-slot="option"][data-highlighted="true"] {
  outline: 2px solid var(--focus-ring);
}

Avoid selectors that depend on private wrapper order unless the wrapper is documented as a public slot.

Sources: shared/en/theming

Optional Theme Packages

The workspace includes starter theme packages:

  • @nake-ui/theme-react
  • @nake-ui/theme-vue
  • @nake-ui/theme-vanilla
  • @nake-ui/theme-solid
  • @nake-ui/theme-svelte
  • @nake-ui/theme-core

These packages demonstrate how to style the public contract. They are not required for behavior and should not be treated as the canonical visual system for all applications.

Sources: shared/en/theming

Route-local Themes Page

Use the route-local Themes page when you need a visual map of semantic roles, light/dark mode behavior, and adapter token differences for the current documentation route.

The page is an entry point for theme package inspection. It does not change the headless contract: primitives still expose behavior through native elements, ARIA, and public data-* attributes.

Sources: shared/en/theming

Token Strategy

If you use tokens, keep them semantic:

  • Surface: background and panel surfaces.
  • Text: primary, muted, inverse, disabled.
  • Border: default, strong, focus.
  • Intent: info, success, warning, danger.
  • Interaction: hover, active, selected, highlighted.

Do not encode primitive state only in token names. The state should still be present in DOM attributes.

Sources: shared/en/theming

Focus And Accessibility

Styling must preserve accessibility:

  • Focus indicators must be visible in light and dark modes.
  • Disabled state must be perceivable and programmatically reflected.
  • Invalid state must not rely on color alone.
  • Floating content must remain readable after flip/shift placement changes.
  • Reduced motion users should not need animation to understand state.

Sources: shared/en/theming

Adapter Notes

  • React examples often import @nake-ui/theme-react/styles.css.
  • Vue examples often import @nake-ui/theme-vue/styles.css.
  • Vanilla examples often import @nake-ui/theme-vanilla/styles.css.
  • Solid examples often import @nake-ui/theme-solid/styles.css.
  • Svelte examples often import @nake-ui/theme-svelte/styles.css.

Theme imports are example convenience, not runtime behavior dependencies.

Sources: shared/en/theming

Pitfalls

  • Styling [class*="active"] while data-state says inactive.
  • Removing outline without replacing it with an accessible focus indicator.
  • Hiding content visually while leaving it reachable to keyboard or screen reader users.
  • Animating closed floating content before hidden and ARIA state update.

Sources: shared/en/theming

Checklist

  • Styles target public contract attributes.
  • Focus, disabled, invalid, selected, highlighted, and open states are visible.
  • Theme mode changes do not remount primitives or reset state.
  • Optional theme packages can be removed without changing behavior.

Sources: shared/en/theming