Skip to content
K

Styling And DSD

CSS, theming, Declarative Shadow DOM, and hydration policy.

v0.1 keeps styling flat and bundler-owned. There is no Naos CSS graph, Sass contract, CSS Modules contract, PostCSS contract, or constructable stylesheet contract.

Inline CSS Text

import css from "./button.css?inline"

export const options = {
  styles: [css],
}

Vite resolves ?inline CSS imports to strings. Naos injects those strings into imperative Shadow DOM and explicit Declarative Shadow DOM output as <style>.

Theming

CSS custom properties are the v0.1 theming mechanism:

button {
  border-color: var(--naos-control-border, #2563eb);
  background: var(--naos-control-bg, #eff6ff);
}

Host pages set variables on the custom element or any ancestor. Parts, slots, ARIA, and data-state attributes are the stable styling and state contracts.

Declarative Shadow DOM

DSD is the standard output of the explicit prerender path. You opt into prerendering static HTML; you do not add a second component mode.

naos prerender src/counter.wc.tsx --props '{"label":"Static"}'

Prerendering emits <template shadowrootmode="open">. The Vite plugin emits build-time metadata by default for static site and demo workflows. Use prerender: false only for builds that intentionally do not need that metadata. Visible data-naos-* markers are internal hydration markers and are not semver-protected.

Hydration Mismatches

In development, hydration mismatches throw structured diagnostics with filename, span, code, severity, message, and hint when available. In production, stale DSD is remounted imperatively so published static pages keep working.