Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

Themes and presets

Set the whole app's look in one place: IzzyTheme in App.razor's head takes a preset, then your brand color, grays, radius, density and fonts over it. It renders on the server, so the theme is there on first paint, with no script and in every render mode.

Set the theme

Put one IzzyTheme in the head, after the stylesheet:

Components/App.razor
<link rel="stylesheet" href="@Assets["_content/IzzyBlazor.Core/izzyblazor.css"]" />
<IzzyTheme Preset="ThemePreset.Soft" Brand="#0a7d5a" Radius="ThemeRadius.Full" />

Each setting beats the preset's own; leave it unset to take the preset's. With none at all you get the Standard preset in blue on neutral grays.

Presets

Use Preset for a starting set of defaults: density, shape, type and colors that suit a kind of app.

Preview

Standard

The default: 36px controls, a medium radius and hairline shadows.

Active

Compact

For dense data and admin: 32px controls, tight rows, a small radius, borders only.

Active

Soft

For consumer apps and portals: 40px controls, roomy, a large radius, gentle shadows.

Active

Editorial

For reading and docs: serif headings over a plain sans, a large radius.

Active

Code

Presets.razor
@* The same card under each preset, described by its card. On part of a page a preset sets density,
   shape and depth only, so each card also takes its preset's brand and gray, and the Editorial card
   sets its fonts with Style (fonts are app-wide, so the preset alone wouldn't change them here). *@
<Grid Columns="new() { Base = 1, Sm = 2 }" Gap="4" Grow>
    @foreach (var set in Sets)
    {
        <IzzyTheme Preset="set.Preset" Brand="@set.Brand" Gray="@set.Gray" Style="@set.Style">
            <Card Title="@set.Preset.ToString()" Description="@set.Description" Height="Length.Full">
                <Row Gap="2" Wrap Align="Align.Center">
                    <Button>Invite</Button>
                    <Button Variant="ButtonVariant.Outline" Accent="Accent.Neutral">Later</Button>
                    <Badge Status="Status.Success">Active</Badge>
                </Row>
            </Card>
        </IzzyTheme>
    }
</Grid>

@code {
    private sealed record PresetSet(ThemePreset Preset, string Brand, string Gray, string Description, string? Style = null);

    private static readonly PresetSet[] Sets =
    [
        new(ThemePreset.Standard, "blue", "neutral", "The default: 36px controls, a medium radius and hairline shadows."),
        new(ThemePreset.Compact, "indigo", "slate", "For dense data and admin: 32px controls, tight rows, a small radius, borders only."),
        new(ThemePreset.Soft, "teal", "neutral", "For consumer apps and portals: 40px controls, roomy, a large radius, gentle shadows."),
        new(ThemePreset.Editorial, "ink", "stone", "For reading and docs: serif headings over a plain sans, a large radius.",
            "font-family: \"IBM Plex Sans\", system-ui, sans-serif; --ib-font-heading: Newsreader, Georgia, \"Times New Roman\", serif"),
    ];
}

On part of a page a preset doesn't bring its brand and gray, so each card sets them too. Fonts are app-wide, so Editorial's don't show here.

PresetForControlsShapeTypeBrandGray
StandardInternal tools, line-of-business36pxMedium radius, hairline shadowInterBlueNeutral
CompactAdmin, ERP, finance, data grids32px, tight rowsSmall radius, borders onlyInterIndigoSlate
SoftConsumer apps, education, health40px, roomyLarge radius, gentle shadowInterTealNeutral
EditorialDocs, publishing, knowledge bases36pxLarge radiusIBM Plex Sans, Newsreader headingsInkStone

Editorial's fonts aren't served with IzzyBlazor: load them yourself, as under Fonts.

Your brand color

Use Brand with a hex color, or the name of a built-in one. It becomes the primary accent: primary buttons, links, focus rings, the field halo, selected rows, switches and sliders.

Preview

blue A link New
ink A link New
indigo A link New
violet A link New
teal A link New
green A link New
rose A link New

Code

Brands.razor
@* The built-in brand colors, each tuned so text holds 4.5:1 on its fill and on every gray. *@
<Stack Gap="3" Grow>
    @foreach (var brand in Names)
    {
        <IzzyTheme Brand="@brand">
            <Row Gap="3" Align="Align.Center" Wrap>
                <Code Width="4.Rem">@brand</Code>
                <Button Size="ControlSize.Sm">Save</Button>
                <Button Size="ControlSize.Sm" Variant="ButtonVariant.Soft">Preview</Button>
                <Anchor Href="#">A link</Anchor>
                <Badge Accent="Accent.Primary">New</Badge>
            </Row>
        </IzzyTheme>
    }
</Stack>

@code {
    private static readonly string[] Names = ["blue", "ink", "indigo", "violet", "teal", "green", "rose"];
}

From a hex color IzzyBlazor works out the fill, the text on it, the color as text and a soft tint, in light and dark, each checked for contrast. In light mode the fill is your color, unless no text can reach 4.5:1 on it; then only its lightness moves. In dark mode a dark color is lifted so controls still show. To set the shades yourself, see Brand shades by hand.

Grays

Use Gray with neutral (the default), slate (cool) or stone (warm, for serif headings), or a hex color for your light page. From a hex color the surfaces, fills, borders and text are worked out in its hue, with the text checked for contrast and a dark set to match. A very light or dark page color is kept light enough for text to read.

razor
<IzzyTheme Gray="slate" />
@* or your light page color; app-wide *@
<IzzyTheme Gray="#f4efe6" />

Radius and density

Use Radius to round everything in proportion: None, Sm, Md (the default), Lg, or Full for pill-shaped controls. Use Density for control heights, table rows and card padding: Compact (32px), Standard (36px) or Comfortable (40px).

Fonts

Body text is Inter, served with IzzyBlazor: browsers download only the character sets a page uses, and nothing once you name another font. Use BodyFont, HeadingFont and MonoFont for your own fonts, and HeadingWeight for the headings' weight. Load any font other than Inter yourself:

razor
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@400;600;700&display=swap" />
<IzzyTheme BodyFont="Sora, system-ui, sans-serif" HeadingWeight="700" />

The Editorial preset uses IBM Plex Sans and Newsreader:

razor
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Newsreader:opsz,wght@6..72,500..600&display=swap" />

App-wide or part of a page

Fonts, HeadingWeight, a hex Gray and Scrollbars (whether the page's own scrollbar is themed too) are app-wide: set them on the IzzyTheme in the head. The rest also work on part of a page; see Theme part of a page.

For a strict Content-Security-Policy, pass your nonce as Nonce: hex colors and fonts come in a small style block.

Next steps