#CSS
A passthrough tagged template for CSS strings. It has no runtime effect — its sole purpose is to tell editors and language tools that the content is CSS, enabling syntax highlighting, autocompletion, and formatting.
#Basic usage
import { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css } from "ilha";
const const styles: string styles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css `
button {
background: teal;
color: white;
}
.label {
font-weight: 700;
}
`;The result is a plain string, identical to what you would get from an untagged template literal.
#Using with the builder
Pass the result to the .css() builder method to attach it to an island:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha , { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css , const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml html } from "ilha";
const const styles: string styles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css `
.title {
font-size: 1.25rem;
font-weight: 700;
}
button {
background: teal;
color: white;
border: none;
}
`;
const const Card: Island<Record<string, unknown>, Record<string, never>> Card = const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> css (const styles: string styles )
.IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<string, never>, Record<string, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<string, never>> render (
() => const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml html `
<div>
<p class="title">Hello</p>
<button>Action</button>
</div>
`,
);#Interpolations
Interpolations work as normal string concatenation — values are inserted as-is with no transformation:
import { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css } from "ilha";
const const accent: "coral" accent = "coral";
const const radius: 4 radius = 4;
const const styles: string styles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css `
button {
background: ${const accent: "coral" accent };
border-radius: ${const radius: 4 radius }px;
}
`;#Difference from .css()
css\`and.css()` are intentionally separate:
| css`` | .css() | |
|---|---|---|
| What it is | Named export, tagged template | Builder chain method |
| Runtime effect | None — returns a plain string | Attaches scoped styles to the island |
| Purpose | Editor tooling support | Actual style attachment |
A common pattern is to use both together: author styles with css`` for tooling support, then pass the result to.css() to attach them:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha , { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css } from "ilha";
const const styles: string styles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css `
p {
color: teal;
}
`; // ← tooling sees CSS here
const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha .IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> css (const styles: string styles ).IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<string, never>, Record<string, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<string, never>> render (() => `<p>hello</p>`); // ← styles are attached here#Organizing styles
For larger islands, keeping styles in a separate variable improves readability and keeps the builder chain focused on structure and behavior:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha , { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css , const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml html } from "ilha";
const const styles: string styles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => string css `
.card {
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1rem;
}
.card-title {
font-size: 1.125rem;
font-weight: 600;
margin: 0 0 0.5rem;
}
.card-body {
color: #4a5568;
}
button {
margin-top: 1rem;
padding: 0.5rem 1rem;
background: teal;
color: white;
}
`;
const const Card: Island<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>> Card = const ilha: IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
context: <T>(key: string, initial: T) => ContextSignal<...>;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<string, never>, Record<string, never>>.state<boolean, "expanded">(key: "expanded", init?: StateInit<Record<string, unknown>, boolean> | undefined): IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>> state ("expanded", false)
.IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>>.on<"button@click">(selectorOrCombined: "button@click", handler: (ctx: HandlerContextFor<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, "click", Record<string, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>> (+1 overload) on ("button@click", ({ state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state }) => state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state .expanded: MarkedSignalAccessor
(value: boolean) => void (+1 overload)
expanded (!state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state .expanded: MarkedSignalAccessor
() => boolean (+1 overload)
expanded ()))
.IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>> css (const styles: string styles )
.IlhaBuilder<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>, Record<string, never>>) => string | RawHtml): Island<Record<string, unknown>, MergeState<Record<string, never>, "expanded", boolean>> render (
({ state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state }) => const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml html `
<div class="card">
<p class="card-title">Title</p>
${state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state .expanded: MarkedSignalAccessor
() => boolean (+1 overload)
expanded () ? const html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml html `<p class="card-body">Content</p>` : ""}
<button>${state: IslandState<MergeState<Record<string, never>, "expanded", boolean>> state .expanded: MarkedSignalAccessor
() => boolean (+1 overload)
expanded () ? "Collapse" : "Expand"}</button>
</div>
`,
);#Notes
- css`` requires editor tooling to provide any benefit. The vscode-styled-components extension and Prettier's
prettier-plugin-styled-componentsrecognize thecsstag and apply CSS formatting automatically. - The tag works with any string content — there is no validation or parsing at runtime. Syntax errors in your CSS will not be caught by ilha itself, only by your editor or browser.