Skip to main content

Themes and styles

Styles in a Lagoon application are not written in CSS: they are generated at every build from SCSS sources of Lagoon.UI* modules and SCSS files of the client project. This page explains how the result is composed, how to customize it, and how to offer multiple themes to the user.

Application style files​

Application SCSS sources are located in Client/resources/styles/. For a single-theme application, the entry point is main.scss:

Client/resources/styles/main.scss
// Use RGAA compatible style
$custom-rgaa: false;
// Label position
$custom-label-outside: false;
// Set the header logo
$header-logo: "~/images/header-logo.png";

// Spinner
$spinner: 'logo';
$sp-color: $primary;

The build compiles this file to Client/wwwroot/_vroot/styles.css. The _vroot folder is build output: do not modify it and do not version it. To change the rendering, always modify the SCSS sources.

No external tool

Compilation is performed by MSBuild tasks from the Lagoon.Build package, before each application build. In Release, the stylesheet is minified; in Debug, it remains readable. The project's <LagoonMinifyCss>true|false</LagoonMinifyCss> property forces one or the other.

Aggregation order​

All sources are merged into a single SCSS document, in this order:

  1. Lagoon.UI: Bootstrap, variables, and component styles;
  2. other referenced Lagoon.UI* modules (Lagoon.UI.GridView, Lagoon.UI.Notifications, …);
  3. the application file (main.scss, or each theme-*.scss).

Override a variable​

Lagoon's SCSS engine has been modified to allow variable redefinition at the global level: the last assignment of a variable applies to the entire document, including styles of modules declared before it. The !default keyword is therefore unnecessary.

Concretely, all variable declarations are grouped before style rules, keeping only the last value of each and reordering them according to their dependencies. A variable assigned in the application file, which is processed last, takes precedence over values defined by modules:

Client/resources/styles/main.scss
// Every Lagoon.UI rule using $primary picks up this value
$primary: #0B5394;
// A variable can reference another one, whatever the declaration order
$sp-color: $primary;

In application files, the ~/ prefix designates the site root (~/images/logo.png). In module sources, it designates the _content/<Module>/ folder of that module.

$custom-* options​

Some boolean variables select an entire set of variables and styles:

VariableEffectDefault value
$custom-rgaaMore contrasted palette and adjustments for accessibility (RGAA).false
$custom-label-outsideLabels displayed above fields, instead of being placed in the field as a placeholder.false

See Accessibility for the use of these options.

Offering multiple themes​

An application can offer multiple themes, for the user to choose from. A theme is a complete stylesheet, compiled from a theme-<nom>.scss file. Themes rely on the same modules and vary their variables (colors, $custom-* options, logos, spinner, …).

Declare themes​

Create a theme-<nom>.scss file per theme in Client/resources/styles/, and place what is common in a shared file imported by each of them:

Client/resources/styles/theme-standard.scss
// Label position
$custom-label-outside: false;
// Use RGAA compatible style
$custom-rgaa: false;

@import "shared";
Client/resources/styles/theme-rgaa.scss
// Use RGAA compatible style
$custom-rgaa: true;
// Label position
$custom-label-outside: true;

@import "shared";
Client/resources/styles/shared.scss
// Set the header logo
$header-logo: "~/images/header-logo.png";

.my-custom-class {
color: $primary;
}

Each theme-<nom>.scss is compiled to _vroot/theme-<nom>.css, and the theme name is the <nom> part of the file (standard and rgaa in the example).

warning
main.scss is ignored

Once a theme-*.scss file exists, main.scss is no longer compiled and styles.css is no longer produced. Move its content to the shared file.

At startup, the server detects themes from the generated theme-*.css files and transmits them to the client. No list needs to be maintained.

Choose the default theme​

The theme applied until the user chooses another one is configured with the App:Theme key in the server's appsettings.json:

Server/appsettings.json
{
"App": {
"Theme": "rgaa"
}
}

If the key is absent, or if it does not match any theme, the first theme in alphabetical order is used.

warning

Only set App:Theme if the application declares themes: without a theme-*.scss file, the homepage would look for a theme-<nom>.css sheet that does not exist.

Let the user choose​

Add LgThemeMenuItem to the menu. It opens, in a small modal window, the theme selection page, which displays one button per theme:

MenuConfiguration.razor
<LgThemeMenuItem />

The label of each button is the translation key theme-<nom>. Declare it in the client project's Dico.xml:

Client/Dico.xml
<string key="theme-standard" fr="Standard" en="Standard" />
<string key="theme-rgaa" fr="RGAA" en="WCAG" />

The choice is applied immediately, without reloading the page, and saved in the browser (key theme in localStorage). It is therefore specific to each browser, not to the user account. If the saved theme cannot be loaded, for example because it was deleted, the application reverts to the default theme.

Change theme programmatically​

The client application (App, available in any component inheriting from LgComponentBase) exposes the themes:

MemberRole
App.ThemesList of available themes (empty for a single-theme application).
App.GetCurrentTheme()Name of the displayed theme.
App.SetTheme(string theme)Applies and saves a theme; raises an ArgumentException if the name is not in App.Themes.

Favicon and icon per theme​

Each theme can have its own tab icon and its own application icon: place favicon-<nom>.ico and icon-<nom>.png in Client/wwwroot/, alongside favicon.ico and icon.png. They are swapped when the theme changes. A theme without a dedicated file uses favicon.ico and icon.png.

Home page (index.html)​

Keep the link to styles.css in the client's index.html, even in a multi-theme application:

Client/wwwroot/index.html
<link rel="stylesheet" href="styles.css?v={APP_VERSION}" />

The server rewrites it on the fly to load the saved theme's or default theme's stylesheet, and adds a preload script for this sheet at the top of the page. The hash of this script is automatically added to the content security policy (CSP).

See also​