Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I configure an Angular Material app with a dynamic theme?

This should be Google-able in seconds but I have been through every search result and there is no clear documentation about how to set up an Angular Material app with a theme, let alone change theme dynamically.

There is this page: https://material.angular.io/guide/theming and all other pages link to there. Nowhere does it give any indication as to which files the SASS shown is supposed to go into. Nowhere does it mention CSS or SCSS or give any reassurance that it is possible to NOT use SASS (Angular CLI offers several options, if you must use SASS to benefit from Material theming then why is this not stated? If you do not need to use SASS then why are there no CSS/SCSS examples?) I have also tried scouring Github for example projects that show how to do this and came up with nothing.

On top of that, I require to be able to change the theme dynamically at runtime based upon color information that will not be available until then. Can anyone here please shed some light on this? I have found every other aspect of Angular and Material to be well documented, why not this?

Q1: Can you use Material themes without SASS? Q2: How and where (which files) do you configure and apply Material themes? Q3: Is it possible to dynamically generate and switch to a different theme at runtime?

like image 400
Disgruntled Wookie Avatar asked Oct 27 '25 21:10

Disgruntled Wookie


1 Answers

I had a similar issue, trying to generate/swap a custom theme at run-time that was not available at build-time (when the sass processes your theme into the Angular Material styles). The solution revolves around CSS variables (not SASS vars), programmatically changing them at run-time:

(assuming you've followed theme setup per the docs here, thus far...)

In your sass/scss theme file:

  • Create variables to house the dynamic colors. Set them to some defaults:
     :root {
        --primary-color: #0a84ff;
        --primary-color-darker: #075cb3;
        --primary-color-lighter: #cee6ff;
        --secondary-color: #ff6917;
        --secondary-color-darker: #e65f15;
        --secondary-color-lighter: #ff965d;
     }
  • Create a custom palette color map that will serve as your default palette:
     $default-primary-palette: (
        50: #ffffff,
        100: #c7e3ff,
        200: #8fc7ff,
        300: var(--primary-color-lighter),
        400: #2993ff,
        500: var(--primary-color),
        600: #0075ea,
        700: #0065cc,
        800: #0056ad,
        900: var(--primary-color-darker),
        A100: #ffffff,
        A200: #a3d1ff,
        A400: #3d9eff,
        A700: #2391ff,
        contrast: (
          50: #000000,
          100: #000000,
          200: #000000,
          300: #000000,
          400: #ffffff,
          500: #ffffff,
          600: #ffffff,
          700: #ffffff,
          800: #ffffff,
          900: #ffffff,
          A100: #000000,
          A200: #000000,
          A400: #ffffff,
          A700: #ffffff,
        ),
      );

could set a variable for every gradient level, if you need it

  • Set this as your theme:
$primary: mat.define-palette($default-primary-palette);
$accent: mat.define-palette($default-accent-palette);
     
$custom-theme: mat.define-light-theme(
  (
    color: (
      primary: $primary,
      accent: $accent,
    )
  )
);

If you process this into CSS, you'll notice that the SCSS pre-processor leaves the "var(--variable)" intact.

  • via CLI: sass --watch styles.scss styles.css
  • OR via Angular build

Now all that is left to do is implementing some programmatic mechanism to set these :root variable values. There are several ways to do this, for example if you only want the changes scoped under a particular CSS class.

This would be one way of changing them globally (at doc > :root):

changePrimaryColor() {
  document.documentElement.style.setProperty('--primary-color', '#990000');
}

^ Kept simple but could of course flesh this out more, based on your color data structure at run-time

like image 179
kflo411 Avatar answered Oct 29 '25 18:10

kflo411



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!