# How to Use themeCSS and themeVariables to Override Default Themes in Mermaid

> Learn to override Mermaid default themes using themeCSS and themeVariables. Customize colors, fonts, and target SVG elements for unique diagrams.

- Repository: [mermaid-js/mermaid](https://github.com/mermaid-js/mermaid)
- Tags: how-to-guide
- Published: 2026-02-23

---

**The `themeCSS` and `themeVariables` configuration options provide complementary mechanisms for customizing Mermaid.js diagrams—`themeVariables` overrides design tokens like colors and fonts, while `themeCSS` injects raw CSS to target specific SVG elements after theme generation.**

The mermaid-js/mermaid library generates diagrams as SVG with calculated styles based on selected themes. By leveraging these two configuration options in `mermaid.initialize()` or in-diagram directives, you can override default themes without maintaining a fork of the repository.

## Understanding the themeCSS Configuration Option

`themeCSS` is a **raw CSS string** appended to the diagram's `<style>` block before generated theme styles are added. In [`packages/mermaid/src/mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaidAPI.ts), the `createCssStyles` function concatenates this value exactly as written:

```typescript
// mermaidAPI.ts → createCssStyles
if (config.themeCSS !== undefined) {
  cssStyles += `\n${config.themeCSS}`;
}

```

Because the CSS is injected **exactly as-written**, you can target any SVG selector that exists in the rendered output, such as `.node rect`, `.edgePath`, or `foreignObject`. This allows you to override specific visual properties that the theme generates, or add effects like drop shadows and custom borders that are not part of the standard design tokens.

## Understanding the themeVariables Configuration Option

`themeVariables` is an **object of design-token values**—including colors, fonts, and sizes—that each built-in theme consumes to calculate its full stylesheet. The default configuration in [`packages/mermaid/src/defaultConfig.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/defaultConfig.ts) establishes the base values:

```typescript
// defaultConfig.ts
themeVariables: theme.default.getThemeVariables(),

```

The type definition in [`packages/mermaid/src/config.type.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/config.type.ts) clarifies the relationship between the two options, noting that you may use `themeCSS` to override values set by `themeVariables`.

During initialization in [`mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/mermaidAPI.ts), the library merges your overrides with the selected theme:

```typescript
// mermaidAPI.ts → initialize
if (options?.theme && options.theme in theme) {
  // merge user overrides with the selected theme
  options.themeVariables = theme[options.theme].getThemeVariables(options.themeVariables);
} else {
  // fall back to the default theme
  options.themeVariables = theme.default.getThemeVariables(options.themeVariables);
}

```

Each theme file (e.g., [`packages/mermaid/src/themes/theme-default.js`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/themes/theme-default.js)) exports a `getThemeVariables` function that instantiates a **Theme** class, applies your overrides, and derives calculated values such as color scales and border contrasts.

## How themeCSS and themeVariables Interact

The two options operate in sequence during the rendering pipeline:

1. **`themeVariables`** determines the computed design tokens (e.g., `nodeBkg`, `edgeLabelBackground`, `fontFamily`) used by the theme's generator.
2. **`themeCSS`** is concatenated **after** those computed styles, enabling fine-tuning or forced overrides of any rule the theme generated.

The final CSS assembly occurs in [`packages/mermaid/src/styles.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/styles.ts), called from [`mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/mermaidAPI.ts):

```typescript
const allStyles = getStyles(graphType, userCSSstyles, config.themeVariables);

```

Here, `userCSSstyles` already contains the raw `themeCSS` string injected during the `createCssStyles` phase.

## Practical Implementation Examples

### Override Colors and Fonts with themeVariables

Use `themeVariables` to modify specific design tokens while preserving the overall theme structure:

```javascript
mermaid.initialize({
  theme: 'forest',
  themeVariables: {
    // Override node appearance
    nodeBkg: '#ffeb3b',
    nodeBorder: '#f57f17',
    // Typography adjustments
    fontFamily: '"Helvetica Neue", Arial, sans-serif',
    fontSize: '14px',
  },
});

```

This example maintains the forest theme's edge styling and layout while forcing nodes to display with a bright yellow background.

### Target Specific Elements with themeCSS

Use `themeCSS` when you need selector-level control that design tokens cannot provide:

```javascript
mermaid.initialize({
  theme: 'default',
  themeCSS: `
    /* Thick red edges */
    .edgePath path { stroke: #e53935; stroke-width: 3px; }

    /* Subtle shadow on nodes */
    .node rect { filter: drop-shadow(2px 2px 2px rgba(0,0,0,0.2)); }
  `,
});

```

Since `themeCSS` is injected after the default stylesheet, you do not need `!important` declarations unless overriding inline styles set by the theme renderer.

### Combining Both for Complete Customization

For comprehensive theming, start with a base theme and layer both options:

```javascript
mermaid.initialize({
  theme: 'dark',
  themeVariables: {
    background: '#2e2e2e',
    fontFamily: '"Fira Code", monospace',
  },
  themeCSS: `
    .node text { text-transform: uppercase; }
    .marker { fill: #ffeb3b; stroke: #ffeb3b; }
  `,
});

```

This approach uses `themeVariables` to adjust the dark theme's foundational tokens while `themeCSS` handles text transformation and arrowhead colors that are not exposed as variables.

### Using In-Diagram Directives

Mermaid also supports configuration via directives within the diagram syntax itself, parsed by [`packages/mermaid/src/utils/sanitizeDirective.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils/sanitizeDirective.ts):

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": { "nodeBkg": "#e0f7fa", "fontFamily": "Arial" },
  "themeCSS": ".node rect { stroke-dasharray: 5,5; }"
}}%%
graph TD
    A --> B

```

These directives populate `config.themeCSS` and `config.themeVariables` identically to JavaScript initialization.

## Key Source Files in the Theming Architecture

Understanding the following files in the `mermaid-js/mermaid` repository clarifies how these configuration options flow through the system:

- **[`packages/mermaid/src/defaultConfig.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/defaultConfig.ts)** - Supplies default `themeVariables` and `themeCSS` entries in the base configuration object.
- **[`packages/mermaid/src/config.type.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/config.type.ts)** - Declares the TypeScript interfaces for `themeCSS` and `themeVariables`, documenting their intended use.
- **[`packages/mermaid/src/mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaidAPI.ts)** - Central hub where options are merged, `themeVariables` are resolved via the selected theme's `getThemeVariables` function, and `themeCSS` is concatenated into the final stylesheet.
- **[`packages/mermaid/src/themes/index.js`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/themes/index.js)** - Maps theme names (`default`, `forest`, `dark`, `base`) to their respective `getThemeVariables` implementations.
- **[`packages/mermaid/src/themes/theme-default.js`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/themes/theme-default.js)** (and sibling theme files) - Implements `getThemeVariables` to build Theme class instances, apply user overrides, and calculate derived values.
- **[`packages/mermaid/src/styles.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/styles.ts)** - Receives processed `themeVariables` and raw `themeCSS` (as `userStyles`) to assemble the final CSS string injected into the SVG.
- **[`packages/mermaid/src/utils/sanitizeDirective.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils/sanitizeDirective.ts)** - Parses in-diagram `init` directives, enabling `themeCSS` and `themeVariables` configuration within Markdown code blocks.

## Summary

- **`themeVariables`** overrides design tokens (colors, fonts, sizes) at the theme level before CSS generation.
- **`themeCSS`** injects raw CSS after theme styles are calculated, enabling selector-level customization of SVG elements.
- **Initialization flow**: User options merge with theme defaults in [`mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/mermaidAPI.ts), then [`styles.ts`](https://github.com/mermaid-js/mermaid/blob/main/styles.ts) assembles the final stylesheet.
- **Directive support**: Both options work within `%%{init: {...}%%` blocks for configuration without JavaScript.

## Frequently Asked Questions

### What is the difference between themeCSS and themeVariables in Mermaid.js?

`themeVariables` is an object of design tokens that modifies how the theme calculates its base styles, affecting properties like `nodeBkg` and `fontFamily` before CSS is generated. `themeCSS` is a raw CSS string appended after theme generation, allowing you to target specific SVG selectors like `.node rect` or `.edgePath` that may not be exposed as variables.

### Can I use themeCSS to override any SVG element in Mermaid diagrams?

Yes. Because `themeCSS` is injected directly into the diagram's `<style>` block as implemented in [`packages/mermaid/src/mermaidAPI.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaidAPI.ts), you can write CSS rules targeting any valid SVG selector rendered by Mermaid, including `.node`, `.edgeLabel`, `foreignObject`, and specific marker elements.

### How do I dynamically change themes after initialization using themeVariables?

While `mermaid.initialize()` sets the base configuration, you can render diagrams with different `themeVariables` by passing a configuration object to `mermaid.render()` or by using in-diagram `%%{init: ...}%%` directives. Each render call processes the provided `themeVariables` fresh through the selected theme's `getThemeVariables` function.

### Is it possible to use themeCSS and themeVariables in Markdown environments?

Yes. Both options are supported through the `init` directive syntax within the diagram definition itself, parsed by [`packages/mermaid/src/utils/sanitizeDirective.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils/sanitizeDirective.ts). This allows you to customize themes in static site generators and Markdown documentation without requiring a JavaScript initialization block.