I had an interesting scenario today where I had to apply a local modified theme, in addition to a global theme. By scss setup looks like:
@import '~@angular/material/theming';
@include mat-core();
@mixin custom-cmp($theme) {
$foreground: map-get($theme, foreground);
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$warn: map-get($theme, warn);
[my-custom-comp],
.my-custom-comp
{
&[text],
&.text
{
color: mat-color($foreground, text);
}
&[primary],
&.primary
{
color: mat-color($primary);
}
&[accent],
&.accent
{
color: mat-color($accent);
}
&[warn],
&.warn
{
color: mat-color($warn);
}
}
}
$my-theme-primary: mat-palette($mat-indigo);
$my-theme-accent: mat-palette($mat-amber);
$my-theme-warn: mat-palette($mat-red);
$my-theme: mat-light-theme($my-theme-primary, $my-theme-accent, $my-theme-warn);
@include angular-material-theme($my-theme);
@include custom-cmp($my-theme);
$my-dark-theme-primary: mat-palette($mat-blue);
$my-dark-theme-accent: mat-palette($mat-amber, A200, A100, A400);
$my-dark-theme-warn: mat-palette($mat-red);
$my-dark-theme: mat-dark-theme($my-dark-theme-primary, $my-dark-theme-accent, $my-dark-theme-warn);
[darktheme=true]
{
@include angular-material-theme($my-dark-theme);
@include custom-cmp($iv-dark-theme);
}
[darktheme=false]
{
@include angular-material-theme($iv-theme);
@include custom-cmp($iv-theme);
}
... and the top level darktheme
attribute is used to control the global theming.
Use !important
#
I did not want to use !important
unless absolutely necessary (also, I couldn't get the syntax to work in the 10 minutes I was trying it).
Use class #
My next attempt was to add higher level css priority to the local component. This SO post seems to suggest that the css priority goes by:
ID > class > attribute
My attempt was to add:
[darktheme=true],
.darktheme // <-- added
{
@include angular-material-theme($my-dark-theme);
@include custom-cmp($iv-dark-theme);
}
[darktheme=false],
.lighttheme // <-- added
{
@include angular-material-theme($iv-theme);
@include custom-cmp($iv-theme);
}
It did not seem to work. Later parsed CSS attributes were taking precedent, suggesting class and attribute have the same priority (at least in Chrome Version 83.0.4103.116 (Official Build) (64-bit))
Further increase CSS priority #
Then, I remembered a trick to artificially boost the priority
[darktheme=true],
.darktheme.darktheme
{
@include angular-material-theme($my-dark-theme);
@include custom-cmp($iv-dark-theme);
}
[darktheme=false],
.lighttheme.lighttheme
{
@include angular-material-theme($iv-theme);
@include custom-cmp($iv-theme);
}
Note to self: should investigate CSS priority.