Theming
RenderConfig(theme = …) picks one of 4 palettes (ThemeName). Each is a ThemeColors record
turned into a stylesheet: one CSS custom property per ThemeVar on :root, plus the rules that consume them.
Default
themed(ThemeName.Default)Dark
themed(ThemeName.Dark)Forest
themed(ThemeName.Forest)Neutral
themed(ThemeName.Neutral)The variables
Every colour and font in the output comes from one of these, so overriding one variable in your own stylesheet restyles
everything that uses it. The table is ThemeVar: each member carries its CSS name and description.
| Variable | Used by |
|---|---|
--mermoid-primary | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-primary-border | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-primary-text | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-secondary | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-secondary-border | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-secondary-text | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-tertiary | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-tertiary-border | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-tertiary-text | unused by built-in rules; palette slot for custom stylesheets |
--mermoid-line | edge stroke, arrowheads, [*] markers |
--mermoid-text | node, edge and subgraph labels |
--mermoid-main-bkg | node fill |
--mermoid-node-border | node stroke, subgraph frame |
--mermoid-background | available for a page/container background |
--mermoid-font-family | all text |
--mermoid-font-size | node and subgraph labels |
--mermoid-edge-label-bg | the rect behind an edge label |
--mermoid-note-bg | note fill |
--mermoid-note-border | note stroke and connector |
--mermoid-note-text | note text |
--mermoid-selection | hybrid is-selected outline |
The primary/secondary/tertiary triples (colour, border, text) are not consumed by the built-in rules; they exist
so a custom stylesheet can pick theme-consistent colours without hardcoding hexes.
resolveVariables
RenderConfig.resolveVariables decides whether the rules reference the variables or the substituted values. It defaults
to true.
true—fill: #1f2020. Self-contained: the SVG renders identically wherever it lands, including contexts that strip<style>or don't cascade (some email clients, some image pipelines). The:rootblock is still emitted.false—fill: var(--mermoid-main-bkg). Overridable: set the variable anywhere up the cascade and the diagram follows. This is what you want when the diagram is inline in a page you control.
/* resolveVariables = true (Dark) */
.node-shape { fill: #1f2020; }
/* resolveVariables = false */
.node-shape { fill: var(--mermoid-main-bkg); }
Overriding a variable from the page, with resolveVariables = false:
.diagram-container {
--mermoid-main-bkg: #eef6ff;
--mermoid-node-border: #2b6cb0;
}
No re-render — the diagram already on the page restyles.
Beyond the four
The built-in themes are a convenience, not a ceiling. Theme.toStylesheet(colors: ThemeColors) accepts a palette you
built yourself, and a whole stylesheet can be merged over any theme — see Custom CSS.
{
import _root_.mermoid.css.*
val mine = Theme.colors(ThemeName.Neutral).copy(nodeBorder = "#d97706", lineColor = "#92400e")
// Theme.toStylesheet(ThemeColors) is the whole extension point: a palette in, a stylesheet out,
// merged over the chosen theme by customStylesheet.
MermoidAscent.svgDiagram(
sample,
RenderConfig(theme = ThemeName.Neutral, customStylesheet = Some(Theme.toStylesheet(mine))),
)
}