Tokens and Tailwind
Use tokens for shared colors and dimensions, class overrides for component roots, and slots for named parts. These APIs are available in host and Shadow DOM modes; the prebuilt iframe runtime owns its own stylesheet.
Try a theme
Section titled “Try a theme”Change the accent or preview theme after incrementing the counter. Styling updates do not replace the document. In Shadow DOM mode, the custom callout and action receive the same application stylesheet through shadowStyles.
Theme tokens
Section titled “Theme tokens”<DilRenderer mode="host" text={source} appearance="dark" tokens={{ "--primary": "#a7f3d0", "--primary-foreground": "#171717", "--radius": "1rem", }}/>Useful variables include --background, --foreground, --primary, --primary-foreground, --muted, --muted-foreground, --border, --ring, --radius, and --chart-1 through --chart-5. Tokens affect adapters that consume them; a DIL tag’s explicit dimensions or radius can still determine its layout.
appearance chooses the stock light/dark theme independently of the surrounding application. Check text, focus, selected, disabled, and status contrast for each theme you supply.
Custom components inherit these variables inside the renderer scope. They must use the variables in their own CSS; passing a token does not rewrite a component’s hardcoded colors.
Class overrides
Section titled “Class overrides”<DilRenderer mode="host" text={source} className="my-message" classNames={{ button: "rounded-full", box: "my-card" }}/>Default classes merge before caller classes where the adapter supports them. Custom components own forwarding their className and slot classes to the correct elements. Do not assume every stock adapter forwards every arbitrary class or CSS prop.
Keep overrides inside the renderer scope. A page-wide rule such as button { … } can also affect your application in host mode. The live examples use a root class, od-docs-output, to constrain their application CSS.
Tailwind v4
Section titled “Tailwind v4”Import one styling entry point: compiled @snackbit/opendil/styles.css, or the Tailwind source below.
@import "@snackbit/opendil/tailwind.css";@source "./src";Include your application source in Tailwind’s scan so consumer class names are generated. Package styles are scoped to .dil-scope and do not install a global reset.
The compiled package stylesheet contains the utilities needed by the stock components. It does not generate arbitrary consumer utilities or classes authored in a DIL response. Compile the classes your custom components use. Host mode can use that application stylesheet directly; Shadow DOM needs the resulting CSS inside its root.
Shadow DOM CSS
Section titled “Shadow DOM CSS”Styles imported into the page do not reach a ShadowRoot. The stock renderer stylesheet is installed automatically, but custom application CSS must be passed through shadowStyles. Supply the compiled CSS as a string, including any utilities your registered components require:
The components registry comes from the custom component guide. customizationStyles is the stylesheet string shown below.
<DilRenderer mode="shadow" text={source} showStatus={false} components={components} className="od-docs-output" classNames={{ Callout: "od-custom-callout", button: "od-custom-action" }} slots={{ Callout: { title: "od-custom-title", body: "od-custom-body" }, }} shadowStyles={customizationStyles}/>shadowStyles applies after the stock stylesheet. It is application code, not a DIL expression or a security boundary.
This is the CSS used by the live demos:
View the application stylesheet
.od-docs-output { padding: 16px; border-radius: 8px;}.od-docs-output .od-custom-callout { display: grid; gap: 8px; padding: 16px; border: 1px solid var(--border); border-left: 3px solid var(--primary); border-radius: var(--radius); background: var(--muted);}.od-docs-output .od-custom-title { font-size: 14px; font-weight: 600;}.od-docs-output .od-custom-title-strong { font-size: 18px; color: var(--primary);}.od-docs-output .od-custom-body { font-size: 14px; line-height: 1.6;}.od-docs-output .od-custom-body p { margin: 0;}.od-docs-output .od-custom-action { border-radius: 999px; padding-inline: 20px;}Boundaries to account for
Section titled “Boundaries to account for”The renderer scope also isolates its theme variables from other messages. Apply app-specific colors through tokens or a scoped stylesheet rather than assuming the website’s --od-* variables are stock renderer tokens.
A ShadowRoot does not contain portals created in document.body. For custom dialogs, tooltips, or menus, choose a portal container inside the same root so that styles and theme variables remain available. If a third-party component requires page-level CSS and body portals, host mode may fit it better.
Styling APIs do not add iframe containment to host or Shadow DOM rendering. See Isolation before choosing a mode for untrusted component code.