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 isNamed export, tagged templateBuilder chain method
Runtime effectNone — returns a plain stringAttaches scoped styles to the island
PurposeEditor tooling supportActual 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 thecss tag 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.