HelpBot Assistant

How can I help you?

Overview of CSS Variables in Themes

2 Feb 202613 minutes to read

CSS variables (also known as CSS custom properties) are custom values defined once and reused throughout stylesheets. They start with a double hyphen (–) and are accessed using the var() function.

Syncfusion® Essential JS 2 (EJ2) Angular components rely heavily on CSS variables to enable flexible, consistent, and maintainable theming. Key benefits include:

  • Easy theme customization without altering core component files
  • Seamless light/dark mode toggling via class application
  • Uniform appearance across all components
  • Runtime dynamic style updates without page reloads
  • Improved maintainability and scalability for large applications

CSS Themes for Syncfusion® Angular Controls

Syncfusion® provides the following modern themes, each available in light and dark variants:

  • Material 3 Theme
  • Fluent 2 Theme
  • Bootstrap 5.3 Theme
  • Tailwind 3.4 Theme

These themes define appearance through CSS variables, enabling straightforward color adjustments and automatic light/dark mode support.

Note: Material 3 uses rgb() values (e.g., –color-sf-primary: 98, 0, 238;) rather than hex codes. This format supports better opacity handling and color manipulation. Using hex values directly may lead to inconsistent rendering.

Obtaining Themes

Syncfusion® themes are available via npm packages or CDN links. Use a recent version for the latest features and fixes.

Theme Light Package / CDN Dark Package / CDN
Material 3 @syncfusion/ej2-material3-theme
https://cdn.syncfusion.com/ej2/32.1.19/material3.css
@syncfusion/ej2-material3-dark-theme
https://cdn.syncfusion.com/ej2/32.1.19/material3-dark.css
Fluent 2 @syncfusion/ej2-fluent2-theme
https://cdn.syncfusion.com/ej2/32.1.19/fluent2.css
@syncfusion/ej2-fluent2-dark-theme
https://cdn.syncfusion.com/ej2/32.1.19/fluent2-dark.css
Bootstrap 5.3 @syncfusion/ej2-bootstrap5.3-theme
https://cdn.syncfusion.com/ej2/32.1.19/bootstrap5.3.css
@syncfusion/ej2-bootstrap5.3-dark-theme
https://cdn.syncfusion.com/ej2/32.1.19/bootstrap5.3-dark.css
Tailwind 3 @syncfusion/ej2-tailwind3-theme
https://cdn.syncfusion.com/ej2/32.1.19/tailwind3.css
@syncfusion/ej2-tailwind3-dark-theme
https://cdn.syncfusion.com/ej2/32.1.19/tailwind3-dark.css

Using npm packages

  1. Install the desired theme:
    npm install @syncfusion/ej2-material3-theme
  2. Import it in your global styles file (src/styles.scss or src/styles.css):
    @import '@syncfusion/ej2-material3-theme/styles/material3.css';

Using CDN

Include the stylesheet in the <head> of your index.html:

<link href="https://cdn.syncfusion.com/ej2/32.1.19/material3.css" rel="stylesheet" />

Using CSS Variables in Modern Themes

Each Syncfusion® theme defines a set of CSS variables that control various aspects of component appearance. These variables follow a consistent naming pattern:

  • Primary Colors: –color-sf-primary, –color-sf-secondary, –color-sf-tertiary
  • Surface Colors: –color-sf-surface, –color-sf-surface-variant, –color-sf-on-surface
  • Semantic Colors: –color-sf-error, –color-sf-warning, –color-sf-success
  • Neutral Colors: –color-sf-white, –color-sf-black, –color-sf-content-bg-color

Below are examples of CSS variable definitions for each theme:

/* rgb() values of material3 theme */
:root {
    --color-sf-black: 0, 0, 0;
    --color-sf-white: 255, 255, 255;
    --color-sf-primary: 103, 80, 164;
    --color-sf-primary-container: 234, 221, 255;
    --color-sf-secondary: 98, 91, 113;
    --color-sf-secondary-container: 232, 222, 248;
    --color-sf-tertiary: 125, 82, 96;
    --color-sf-tertiary-container: 255, 216, 228;
    --color-sf-surface: 255, 255, 255;
    --color-sf-surface-variant: 231, 224, 236;
    --color-sf-background: var(--color-sf-surface);
    --color-sf-on-primary: 255, 255, 255;
    --color-sf-on-primary-container: 33, 0, 94;
    --color-sf-on-secondary: 255, 255, 255;
    --color-sf-on-secondary-container: 30, 25, 43;
    --color-sf-on-tertiary: 255, 255, 255;
  }
/* Hex values of fluent2 theme */
:root {
    --color-sf-black: #000;
    --color-sf-white: #fff;
    --color-sf-primary: #0f6cbd;
    --color-sf-primary-text-color: #fff;
    --color-sf-primary-light: #b4d6fa;
    --color-sf-primary-lighter: #ebf3fc;
    --color-sf-primary-dark: #0f548c;
    --color-sf-primary-darker: #0c3b5e;
    --color-sf-success: #0e700e;
    --color-sf-info: #008aa9;
    --color-sf-warning: #bc4b09;
    --color-sf-danger: #d13438;
    --color-sf-success-light: #54b054;
    --color-sf-info-light: #56bfd7;
    --color-sf-warning-light: #fee5d7;
    --color-sf-danger-light: #eeacb2;
    --color-sf-success-dark: #54b054;
    --color-sf-info-dark: #56bfd7;
    --color-sf-warning-dark: #8a3707;
    --color-sf-danger-dark: #6e0811;
  }
:root {
    --color-sf-black: 0, 0, 0;
    --color-sf-white: 255, 255, 255;
    --color-sf-content-bg-color: #fff;
    --color-sf-content-bg-color-alt1: #f8f9fa;
    --color-sf-content-bg-color-alt2: #e9ecef;
    --color-sf-content-bg-color-alt3: #dee2e6;
    --color-sf-content-bg-color-alt4: #ced4da;
    --color-sf-content-bg-color-alt5: #adb5bd;
    --color-sf-content-bg-color-hover: #f8f9fa;
    --color-sf-content-bg-color-pressed: #e9ecef;
    --color-sf-content-bg-color-focus: #e9ecef;
    --color-sf-content-bg-color-selected: #0d6efd;
    --color-sf-content-bg-color-dragged: #ced4da;
    --color-sf-content-bg-color-disabled: #e9ecef;
    --color-sf-flyout-bg-color: #fff;
    --color-sf-flyout-bg-color-hover: #f8f9fa;
    --color-sf-flyout-bg-color-pressed: #0d6efd;
    --color-sf-flyout-bg-color-focus: #f8f9fa;
    --color-sf-overlay-bg-color: 0, 0, 0;
    --color-sf-table-bg-color-hover: rgba(0, 0, 0, .07);
}
:root{
  --color-sf-content-bg-color: rgba(255, 255, 255);
  --color-sf-content-bg-color-alt1: #f9fafb;
  --color-sf-content-bg-color-alt2: #f3f4f6;
  --color-sf-content-bg-color-alt3: #e5e7eb;
  --color-sf-content-bg-color-alt4: #9ca3af;
  --color-sf-content-bg-color-alt5: #6b7280;
  --color-sf-content-bg-color-hover: #f9fafb;
  --color-sf-content-bg-color-pressed: #f3f4f6;
  --color-sf-content-bg-color-focus: #f9fafb;
  --color-sf-content-bg-color-selected: #e5e7eb;
  --color-sf-content-bg-color-dragged: #f3f4f6;
  --color-sf-content-bg-color-disabled: #ffffff;
  --color-sf-flyout-bg-color: #ffffff;
  --color-sf-flyout-bg-color-hover: #f3f4f6;
  --color-sf-flyout-bg-color-pressed: #e5e7eb;
  --color-sf-flyout-bg-color-focus: #f3f4f6;
  --color-sf-flyout-bg-color-selected: #e5e7eb;
  --color-sf-flyout-bg-color-disabled: #fff;
  --color-sf-overlay-bg-color: rgba(107, 114, 128, 74.9);
  --color-sf-table-bg-color-hover: #f9fafb;
  --color-sf-table-bg-color-pressed: #f3f4f6;
  --color-sf-table-bg-color-selected: #e5e7eb;
  --color-sf-text-input-bg-color: #ffffff;
  --color-sf-treeview-item-active-hover-bg: #e5e7eb;
}

Customizing Themes with CSS Variables

Override variables in your application styles after the theme import to customize appearance while preserving consistency.

Material 3 primary color customization example:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { ButtonModule } from '@syncfusion/ej2-angular-buttons'
import { enableRipple } from '@syncfusion/ej2-base'
import { FormsModule } from '@angular/forms'

import { Component } from '@angular/core';

@Component({
imports: [
        
        ButtonModule,
        FormsModule
    ],


standalone: true,
    selector: 'app-root',
    styleUrls:['./styles.css'],
    template:`<div>   
     <!-- Primary Button - Used to represent a primary action. -->
     <button ejs-button cssClass="e-primary">Button</button>
     </div>`  
})

export class AppComponent { 
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Default Material 3 Primary
default primary value

Customized Material 3 Primary
customized primary value

Bootstrap 5.3 theme customization

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { ButtonModule } from '@syncfusion/ej2-angular-buttons'
import { enableRipple } from '@syncfusion/ej2-base'
import { FormsModule } from '@angular/forms'
import { Component } from '@angular/core';

@Component({
imports: [ 
        ButtonModule,
        FormsModule
    ],
    standalone: true,
    selector: 'app-root',
    styleUrls:['./styles.css'],
    template:`<div>   
     <!-- Primary Button - Used to represent a primary action. -->
     <button ejs-button cssClass="e-primary">Button</button>
     </div>`  
})

export class AppComponent { 
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Default Bootstrap 5.3 Primary Value

default primary value

Customized Bootstrap 5.3 Primary Value

customized primary value

Similar overrides work for other themes.Some themes like Fluent 2, Bootstrap 5.3, etc., require updating multiple related variables (e.g., hover and pressed states) for consistency. For comprehensive customizations requiring coordinated changes (e.g., hover, active states), use the Theme Studio to generate consistent values.

Light and Dark Mode Switching

All themes support light/dark variants. To enable dark mode, add the e-dark-mode class to the <body> tag.

Example toggle implementation (Material 3):

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { ButtonModule, CheckBoxModule } from '@syncfusion/ej2-angular-buttons'
import { enableRipple } from '@syncfusion/ej2-base'
import { SwitchModule} from '@syncfusion/ej2-angular-buttons'
import { FormsModule } from '@angular/forms'
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';

@Component({
imports: [
        
        ButtonModule,
        CheckBoxModule,
        SwitchModule,
        FormsModule,
        CommonModule
    ],


standalone: true,
    selector: 'app-root',
    styleUrls:['./styles.css'],
    template:`<div [ngClass]="{'e-dark-mode': isChecked, 'dark': isChecked}">
    <ejs-checkbox label="Enable Darkmode" (change)="toggleCheckbox()"></ejs-checkbox><br/>
   
     <!-- Primary Button - Used to represent a primary action. -->
     <button ejs-button cssClass="e-primary">Button</button>
   
     <!-- Success Button - Used to represent a positive action. -->
     <button ejs-button cssClass="e-success">Button</button>
   
     <!-- Info Button - Used to represent an informative action -->
     <button ejs-button cssClass="e-info">Button</button>
   
     <!-- Warning Button - Used to represent an action with caution. -->
     <button ejs-button cssClass="e-warning">Button</button>
   
     <!-- Danger Button - Used to represent a negative action. -->
     <button ejs-button cssClass="e-danger">Button</button>
     </div>`  
})

export class AppComponent { 
  public className:string="";
  public checked:boolean=true;

  public isChecked = false;

  toggleCheckbox() {
    this.isChecked = !this.isChecked;
    if (this.isChecked) {
      document.body.classList.add('dark');
    }
    else{
      document.body.classList.remove('dark');
    } 
  }
  
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Dark Mode Example
dark mode

The same e-dark-mode class activates dark variants in Fluent 2, Bootstrap 5.3, and Tailwind 3 themes, adjusting backgrounds, text, and accents for readability and contrast.

Theme Studio Application

For advanced customization, use the web-based Syncfusion® Theme Studio. It allows you to:

  • Interactively customize colors
  • Preview changes across components in real time
  • Toggle between light and dark modes
  • Generate and export custom theme CSS files