Osirion.Blazor.Theming gives Osirion components a light and a dark theme, maps their colors onto Bootstrap,
Fluent UI, MudBlazor or Radzen, and lets visitors switch between the themes. It has two components:
OsirionStyleslinks the stylesheets and applies the visitor's theme. Render it once, in your main layout.ThemeToggleis a button that switches between light and dark.
Neither needs an interactive render mode. Both load a small script, so the theme switch needs JavaScript.
Setup
Set the framework and the default theme in appsettings.json:
{
"Osirion": {
"Theming": {
"Framework": "Bootstrap",
"DefaultMode": "System"
}
}
}
Register theming and the script loader in Program.cs. AddOsirion(builder.Configuration) from the meta-package
reads the same section; with the Osirion.Blazor.Theming package alone, call AddOsirionTheming:
using Osirion.Blazor.Theming.Extensions;
builder.Services.AddOsirionTheming(builder.Configuration);
builder.Services.AddJSComponents();
AddJSComponents registers the loader that Osirion components use for their scripts. The same setup in code:
using Osirion.Blazor.Components;
using Osirion.Blazor.Theming.Extensions;
builder.Services.AddOsirionTheming(theming => theming
.UseFramework(CssFramework.Bootstrap)
.Configure(options => options.DefaultMode = ThemeMode.System));
Then render the components in your layout:
@using Osirion.Blazor.Theming.Components
@inherits LayoutComponentBase
<header>
<ThemeToggle />
</header>
<main>
@Body
</main>
<OsirionStyles />
OsirionStyles does not load the CSS framework itself. Reference Bootstrap, Fluent UI, MudBlazor or Radzen the way
that framework documents.
Options
These are the ThemingOptions the components read, bound from Osirion:Theming:
| Option | Type | Default | Description |
|---|---|---|---|
Framework |
CssFramework |
None |
None, Bootstrap, FluentUI, MudBlazor or Radzen. Selects the adapter. |
DefaultMode |
ThemeMode |
System |
The theme before the visitor picks one: Light, Dark or System (follow the operating system). |
UseDefaultStyles |
bool |
false |
When true, only the Core stylesheets are linked; the adapter and the theme stylesheet are left out. |
CustomVariables |
string? |
null |
CSS declarations written into a :root block, for example --osirion-font-family-base: Inter, sans-serif;. They do not override the theme colors or an adapter's values; see Styling. |
EnableDarkMode only affects IThemeService.SetThemeMode on the server; ThemeToggle switches in the browser and
ignores it. FollowSystemPreference is bound but not read by the components; set DefaultMode to System instead.
The parameterless AddOsirionTheming() registers different defaults: UseDefaultStyles on and DefaultMode set to
Light.
How the theme is applied
The current theme lives on the <html> element:
data-osirion-themeislightordark, anddata-osirion-frameworknames the framework.- The framework's own marker is set too:
data-bs-themefor Bootstrap, themud-theme-darkclass for MudBlazor,fluent-dark-themeorfluent-light-themefor Fluent UI, andrz-dark-themefor Radzen. With Fluent UI Blazor v5, the mode is also passed toBlazor.theme.setThemeMode, so Fluent components follow the toggle. - The visitor's choice is stored in the
osirion-preferred-themecookie for one year.OsirionStylesapplies it while the page is parsed, and the server reads it soThemeTogglerenders with the right icon. - With
DefaultModeset toSystemand no stored choice, the theme followsprefers-color-scheme, including changes while the page is open.
Framework adapters
An adapter maps Osirion's design tokens onto the framework's variables: --bs-* for Bootstrap, --mud-palette-* for
MudBlazor, the Fluent UI v5 tokens (--colorNeutralBackground1 and so on, with the v4 tokens as fallback) and
--rz-* for Radzen. Its rules apply under a class on <html> that comes from the configured framework:
osirion-bootstrap-integration, osirion-fluent-integration, osirion-mudblazor-integration or
osirion-radzen-integration. Osirion components then take their colors from your framework theme in both modes.
The repository has one example site per framework (examples/Osirion.Blazor.Example.Bootstrap, .FluentUI and
.Mud). The MudBlazor example shows a MudBlazor theme that follows ThemeToggle without a round trip.
Styling
Osirion components read CSS custom properties such as --osirion-background-primary, --osirion-text-primary,
--osirion-border-color, --osirion-action-primary and --osirion-link-color. The theme stylesheet sets them under
:root[data-osirion-theme=light] and :root[data-osirion-theme=dark], which are more specific than a plain :root
block, so CustomVariables cannot change them.
Without an adapter, override them per theme in your own stylesheet. Putting html in front of the theme's selector
makes your rule win whatever order the stylesheets load in:
html:root[data-osirion-theme="light"] {
--osirion-action-primary: #0b5ed7;
}
html:root[data-osirion-theme="dark"] {
--osirion-action-primary: #6ea8fe;
}
With an adapter, change the framework's variables instead (for Bootstrap, variables such as --bs-primary): the adapter
derives Osirion's tokens from them under html.osirion-bootstrap-integration and similar selectors. Every adapter
also sets --osirion-font-family-base from the framework's font, so with an adapter the font comes from the framework.
Related
- OsirionStyles
- ThemeToggle
- Navigation: place the toggle in a
Menu. - Osirion.Blazor.Theming on NuGet
Related Articles
