4

I have difficulties changing colour of foreground in angular 2 material. For example in toolbar, text is black. I tried to change it with following styles

@import '~@angular/material/theming';

$primary: mat-palette($mat-cyan, 300);
$accent : mat-palette($mat-yellow, 500);;
$warn : mat-palette($mat-red, 600);

$theme-foreground: (
  base:              gray,
  divider:           $white-12-opacity,
  dividers:          $white-12-opacity,
  disabled:          rgba(200, 200, 200, 0.38),
  disabled-button:   rgba(200, 200, 200, 0.38),
  disabled-text:     rgba(200, 200, 200, 0.38),
  hint-text:         rgba(200, 200, 200, 0.38),
  secondary-text:    rgba(200, 200, 200, 0.54),
  icon:              rgba(200, 200, 200, 0.54),
  icons:             rgba(200, 200 , 200, 0.54),
  text:              rgba(200, 200, 200, 0.87),
  slider-min:        rgba(200, 200, 200, 0.87),
  slider-off:        rgba(200, 200, 200, 0.26),
  slider-off-active: rgba(200, 200, 200, 0.38),
);

$theme-background: (
  status-bar: map_get($mat-grey, 300),
  app-bar:    map_get($mat-grey, 100),
  background: map_get($mat-grey, 50),
  hover:      rgba(200, 200, 200, 0.04), // TODO(kara): check style with Material Design UX
  card:       white,
  dialog:     white,
  disabled-button: $black-12-opacity,
  raised-button: white,
  focused-button: $black-6-opacity,
  selected-button: map_get($mat-grey, 300),
  selected-disabled-button: map_get($mat-grey, 400),
  disabled-button-toggle: map_get($mat-grey, 200),
  unselected-chip: map_get($mat-grey, 300),
);

$theme: (
    primary: $primary,
    accent: $accent,
    warn: $warn,
    is-dark: true,
    foreground: $theme-foreground,
    background: $theme-background
  );

@include mat-core();

@include angular-material-theme($theme);

Primary and accent colours are changed, but the frontend did not change. How can I fix it?

I also tried to set toolbar theme, but there wasn't any difference.

Ralf Bönning
  • 14,515
  • 5
  • 49
  • 67
Boris
  • 726
  • 1
  • 10
  • 22

3 Answers3

0

The way you're setting the custom foreground and background is correct - however, for toolbar the font color is decided as follows:

  • if the toolbar is set to primary/accent/warn colors, use the default-contrast color
  • otherwise use the foreground text color

In other words, if your toolbar color is using the primary palette, you're going to have to play around with the contrast colors for $primary - don't recommend this as any number of material components use these. Best to go the old fashioned way and change your toolbar color manually.

If you're really determined to, you can make a custom primary/accent palette with the contrast colors you want and use that to create your theme, like this: https://github.com/angular/material2/blob/master/src/lib/core/theming/_palette.scss

I suggest sticking to greyscale colors for contrast - in some cases Material takes a color and inverts it, so you may end up with something wacky.

0

I want to elaborate a little bit with some details.

I believe, the comment from @toongeorges is the way how Angular Material appearance should be customised in a way how it is intended to be customised. Therefore, the limitations this approach have are intended to give a consistent appearance according to the Material style specification/across different components and so on.

The way you try to customise it is a kind of hacky way, but still should work. You may want to use it in case if the default Material styles is not exactly what you want. However, any hacky tricks require understanding of what's happening under the hood.

Here is the angular-material-theme function you use:

// @deprecated Use `all-component-themes`.
@mixin angular-material-theme($theme-or-color-config) {
  @include all-component-themes($theme-or-color-config);
}

It actually applies the $theme-or-color-config to each and every component in Material. So when you are not sure why a certain component doesn't look in expected way, you should take a look at the styles and understand what exactly is assigned and why.

It seems like toolbar color styles are applied here which is called from here. The crucial thing you may notice is that colors are taken from the $config. This is cause those values are actually stored on the color configuration level.

Note: Honestly speaking, they've got functions and properties named like config_or_theme which were probably made for a sake of backwards compatibility, so if you mix something on the $theme level, it may work. But most likely, not everywhere and this substitution will be dropped in future releases.

Anyway, the object you usually create based on Material docs:

$my-theme: mat.define-light-theme((
 color: (
   primary: $my-primary,
   accent: $my-accent,
   warn: $my-warn,
 ),
 typography: mat.define-typography-config(),
 density: 0,
));

will be actually converted in something like this for Material internal usage:

(
 color: (
   primary: $my-primary,
   accent: $my-accent,
   warn: $my-warn,
   is-dark: false,
   foreground: palette.$light-theme-foreground-palette,
   background: palette.$light-theme-background-palette,
 ),
 typography: mat.define-typography-config(),
 density: 0,
)

Therefore, if you want to be sure that your custom foreground/background is applied properly, you should do something like:

$primary: mat-palette($mat-cyan, 300);
$accent : mat-palette($mat-yellow, 500);;
$warn : mat-palette($mat-red, 600);

// define-dark will create a dark one, so you don't have to override it
$my-theme: mat.define-dark-theme((
 color: (
   primary: $my-primary,
   accent: $my-accent,
   warn: $my-warn,
 ),
 typography: mat.define-typography-config(),
 density: 0,
));

$theme-foreground: (
  base:              gray,
  divider:           $white-12-opacity,
  dividers:          $white-12-opacity,
  disabled:          rgba(200, 200, 200, 0.38),
  disabled-button:   rgba(200, 200, 200, 0.38),
  disabled-text:     rgba(200, 200, 200, 0.38),
  hint-text:         rgba(200, 200, 200, 0.38),
  secondary-text:    rgba(200, 200, 200, 0.54),
  icon:              rgba(200, 200, 200, 0.54),
  icons:             rgba(200, 200 , 200, 0.54),
  text:              rgba(200, 200, 200, 0.87),
  slider-min:        rgba(200, 200, 200, 0.87),
  slider-off:        rgba(200, 200, 200, 0.26),
  slider-off-active: rgba(200, 200, 200, 0.38),
);

$theme-background: (
  status-bar: map_get($mat-grey, 300),
  app-bar:    map_get($mat-grey, 100),
  background: map_get($mat-grey, 50),
  hover:      rgba(200, 200, 200, 0.04),
  card:       white,
  dialog:     white,
  disabled-button: $black-12-opacity,
  raised-button: white,
  focused-button: $black-6-opacity,
  selected-button: map_get($mat-grey, 300),
  selected-disabled-button: map_get($mat-grey, 400),
  disabled-button-toggle: map_get($mat-grey, 200),
  unselected-chip: map_get($mat-grey, 300),
);

$color: map.get($theme, color);

$background: map.merge(map.get($color, background), $theme-background);
$foreground: map.merge(map.get($color, foreground), $theme-foreground);

// overriding color background/foreground
$color: map.merge($color, (background: $background, foreground: $foreground));
$my-theme: map.merge($my-theme, (color: $color));

@include mat-core();

@include angular-material-theme($my-theme);

-1

Try defining your own theme, where you can also define the foreground colour as explained here:

How can I use custom theme palettes in Angular?

Update because of the down votes, which may be from people who do not know how material design works:

If you have no idea how Material Design works, please read first an excellent guide https://tomastrajan.medium.com/the-complete-guide-to-angular-material-themes-4d165a9d24d1 and check the official documentation at https://material.io/design/material-theming/overview.html#material-theming

About the comment to this post, Material Design does not know about a foreground colour. I understand people mean with "foreground" colour, the colour of the font. There is not one such colour, there are multiple colours. You need to understand more about theming in Angular how to set the colour of the font. I briefly explain below.

Material Design uses primary, accent and warn colours which are used differently by each component.

You define the primary, accent and warn colours with mat-palette, which takes a style as shown in the accepted answer at How can I use custom theme palettes in Angular? as first argument. Material Design uses a default, lighter and darker variant for each colour, which by default are the colours defined for the keys 500, 100 and 700. You can change the variants by providing more arguments to mat-palette.

In the theme definition of each colour (primary, accent and warn), there is a contrast entry. Under the contrast entry you find the colours for the font that correspond with the colour variants defined for the theme.

The StackOverflow post I am referring to explains in depth things like

The contrast sets the font color over those background colors.

There is no need for me to reexplain what someone else has already explained very well. It is better for me to just link to the explanation. It is out of my control however that I get down voted, because Material Design does not know the concept of a "foreground" colour, but uses different terminology.

toongeorges
  • 1,844
  • 17
  • 14