Skip to content

css

A passthrough tagged template for CSS strings that enables editor tooling and syntax highlighting.

Updated View as Markdown

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)[]) => stringcss } from "ilha";

const const styles: stringstyles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss`
  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: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
, { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss } from "ilha";
const const styles: stringstyles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss` .title { font-size: 1.25rem; font-weight: 700; } button { background: teal; color: white; border: none; } `; const const Card: Island<RootInput, RootState>Card =
const ilha: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<RootInput, RootState, RootDerived, RootActions>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<RootInput, RootState, RootDerived, RootActions>css(const styles: stringstyles) .IlhaBuilder<RootInput, RootState, RootDerived, RootActions>.render(fn: (ctx: RenderContext<RootInput, RootState, RootDerived, RootActions>) => string | RawHtml): Island<RootInput, RootState>render(() => ( <"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div> <"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p class?: RawHtml | ClassValue | undefinedclass="title">Hello</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p> <
"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
    popovertarget?: string;
    popoverTarget?: string;
    popovertargetaction?: "hide" | "show" | "toggle";
    popoverTargetAction?: "hide" | "show" | "toggle";
}>
button
>Action</
"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
    popovertarget?: string;
    popoverTarget?: string;
    popovertargetaction?: "hide" | "show" | "toggle";
    popoverTargetAction?: "hide" | "show" | "toggle";
}>
button
>
</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>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)[]) => stringcss } from "ilha";

const const accent: "coral"accent = "coral";
const const radius: 4radius = 4;

const const styles: stringstyles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss`
  button {
    background: ${const accent: "coral"accent};
    border-radius: ${const radius: 4radius}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: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
, { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss } from "ilha";
const const styles: stringstyles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss` p { color: teal; } `; // ← tooling sees CSS here
const ilha: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<RootInput, RootState, RootDerived, RootActions>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<RootInput, RootState, RootDerived, RootActions>css(const styles: stringstyles).IlhaBuilder<RootInput, RootState, RootDerived, RootActions>.render(fn: (ctx: RenderContext<RootInput, RootState, RootDerived, RootActions>) => string | RawHtml): Island<RootInput, RootState>render(() => <"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>hello</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>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: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
, { const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss } from "ilha";
const const styles: stringstyles = const css: (strings: TemplateStringsArray | string, ...values: (string | number)[]) => stringcss` .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<RootInput, MergeState<RootState, "expanded", boolean>>Card =
const ilha: RootBuilder & DirectIslandFactory & {
    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;
    ... 5 more ...;
    onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<RootInput, RootState, RootDerived, RootActions>.state<boolean, "expanded">(key: "expanded", init?: StateInit<RootInput, boolean> | undefined): IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions>state("expanded", false) .IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions>.action<"toggleExpanded", undefined, void>(key: "toggleExpanded", fn: (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void): IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void>>action("toggleExpanded", (_: undefined_, { state: IslandState<MergeState<RootState, "expanded", boolean>>state }) => state: IslandState<MergeState<RootState, "expanded", boolean>>state.
expanded: MarkedSignalAccessor
(value: SignalSetter<boolean>) => void (+1 overload)
expanded
((expanded: booleanexpanded) => !expanded: booleanexpanded),
) .IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<...>) => void>>.css(strings: TemplateStringsArray | string, ...values: (string | number)[]): IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void>>css(const styles: stringstyles) .IlhaBuilder<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<...>) => void>>.render(fn: (ctx: RenderContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived, RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void>>) => string | RawHtml): Island<RootInput, MergeState<RootState, "expanded", boolean>>render(({ state: IslandState<MergeState<RootState, "expanded", boolean>>state, action: IslandActions<RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void>>action }) => ( <"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div class?: RawHtml | ClassValue | undefinedclass="card"> <"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p class?: RawHtml | ClassValue | undefinedclass="card-title">Title</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p> {state: IslandState<MergeState<RootState, "expanded", boolean>>state.
expanded: MarkedSignalAccessor
() => boolean (+1 overload)
expanded
() ? <"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p class?: RawHtml | ClassValue | undefinedclass="card-body">Content</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p> : ""}
<
"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
    popovertarget?: string;
    popoverTarget?: string;
    popovertargetaction?: "hide" | "show" | "toggle";
    popoverTargetAction?: "hide" | "show" | "toggle";
}>
button
onclick?: NativeEventHandler<PointerEvent & {
    readonly currentTarget: HTMLButtonElement;
}> | undefined
onclick
={action: IslandActions<RootActions & Record<"toggleExpanded", (props: undefined, ctx: ActionContext<RootInput, MergeState<RootState, "expanded", boolean>, RootDerived>) => void>>action.toggleExpanded: ActionAccessor<undefined, void>toggleExpanded}>
{state: IslandState<MergeState<RootState, "expanded", boolean>>state.
expanded: MarkedSignalAccessor
() => boolean (+1 overload)
expanded
() ? "Collapse" : "Expand"}
</
"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
    popovertarget?: string;
    popoverTarget?: string;
    popovertargetaction?: "hide" | "show" | "toggle";
    popoverTargetAction?: "hide" | "show" | "toggle";
}>
button
>
</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div> ));

Notes

  • css requires editor tooling to provide any benefit. The vscode-styled-components extension and Prettier’s prettier-plugin-styled-components recognize the css 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.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close