Angular Material custom colors
Asked Answered
L

4

3

I would like to have access to more than 3 colors for my material theme. For example, I would like to add in $theme-success: mat-pallete($mat-green) to have a green success color in my Material components like md-checkbox color="success".

@import '~@angular/material/theming';
@include mat-core();

$theme-primary: mat-palette($mat-blue);
$theme-accent: mat-palette($mat-yellow, A400, A200, A600);
$theme-warn: mat-palette($mat-red);
$theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);

.body-light {
  @include angular-material-theme($theme);
}

Is this possible?

Leekgreen answered 7/7, 2017 at 18:24 Comment(0)
B
5

The color bindings only support primary, accent, and warn.

If the coloring is simple (for checkbox, it's just .mat-checkbox-background and .mat-ripple-element), you can use the palette yourself:

$theme-success: mat-palette($mat-green);

.mat-checkbox-ripple .mat-ripple-element {
  background-color: mat-color($theme-success, 0.26);
}

You could probably also get away with making 2 themes, where the second one uses your success color for primary

$theme-primary: mat-palette($mat-blue);
$theme-accent: mat-palette($mat-yellow, A400, A200, A600);
$theme-warn: mat-palette($mat-red);
$theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);

$theme-success: mat-palette($mat-green);
$theme2: mat-light-theme($theme-success, $theme-accent, $theme-warn);

.body-light {
  @include angular-material-theme($theme);
}

.component-success {
  @include angular-material-theme($theme2);
}
Backler answered 10/7, 2017 at 20:7 Comment(1)
I found this very helpful. Thank you!Leekgreen
K
4

Also, if you really need an extra color you can create class in styles.scss (or.css) or anywhere in your style sheets.

.mat-buttonSuccess{
    background-color: #ffff00;
    color: #000;
}

and then call it as color same way as primary, accent and warn.

<button mat-raised-button color="buttonSuccess">Success</button>
Kevel answered 18/7, 2018 at 10:22 Comment(0)
U
1

I did the following to make full use of the button features

  1. I created a palette on my main theme file, _theme.scss

@import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$my-app-primary: mat-palette($mat-deep-purple);
$my-app-accent:  mat-palette($mat-amber, A200, A100, A400);
$my-app-green:  mat-palette($mat-green);  // <------ My new palette

// The warn palette is optional (defaults to red).
$my-app-warn:    mat-palette($mat-red);

// Create the theme object (a Sass map containing all of the palettes).
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($my-app-theme);

@import './buttons';
  1. I defined my override in _buttons.scss

.mat-raised-button {
  &.mat-green {
    color: mat-color($my-app-green, darker-contrast);
    background-color: mat-color($my-app-green, default);
    
    &[disabled] {
      color: mat-color($mat-light-theme-foreground, disabled-button);
      background-color: mat-color($mat-light-theme-background, disabled-button);
    }

    .mat-ripple-element {
      @include _mat-button-ripple-background($my-app-green, darker-contrast, $_mat-button-ripple-opacity);
    }
  }
}

Everything I needed to figure these out are in \node_modules\@angular\material\_theming.scss

And a starting point from here

Unsuccess answered 2/4, 2020 at 22:53 Comment(0)
L
1

With angular 15 in 2023 you can use next mixin for applying color="success" and color="info":

mat-button-variants.scss

@use 'sass:map';
@use 'sass:meta';
@use '@angular/material' as mat;

$_ripple-opacity: 0.1;

// Applies a focus style to an mat-button element for each of the supported palettes.
@mixin _focus-overlay-color($config-or-theme, $variants) {
  $config: mat.get-color-config($config-or-theme);
  @each $variant, $variant-palette in $variants {
    &.mat-#{$variant} .mat-button-focus-overlay {
      background-color: mat.get-color-from-palette($variant-palette);
    }
  }
}

@mixin _ripple-background($palette, $hue, $opacity) {
  $background-color: mat.get-color-from-palette($palette, $hue, $opacity);
  background-color: $background-color;
  @if (meta.type-of($background-color) != color) {
    opacity: $opacity;
  }
}

@mixin _ripple-color($theme, $hue, $opacity, $variants) {
  @each $variant, $variant-palette in $variants {
    &.mat-#{$variant} .mat-ripple-element {
      @include _ripple-background($variant-palette, $hue, $opacity);
    }
  }
}

// Applies a property to an mat-button element for each of the supported palettes.
@mixin _theme-property($theme, $property, $hue, $variants) {
  $background: map.get($theme, background);
  $foreground: map.get($theme, foreground);

  @each $variant, $variant-palette in $variants {
    &.mat-#{$variant} {
      #{$property}: mat.get-color-from-palette($variant-palette, $hue);
    }

    &.mat-#{$variant} {
      &.mat-button-disabled {
        $palette: if($property == 'color', $foreground, $background);
        #{$property}: mat.get-color-from-palette($palette, disabled-button);
      }
    }
  }
}

@mixin color($config-or-theme, $variants) {
  $config: mat.get-color-config($config-or-theme);
  $foreground: map.get($config, foreground);
  $background: map.get($config, background);

  .mdc-button:not(:disabled),
  .mat-mdc-icon-button:not(:disabled),
  .mat-mdc-stroked-button:not(:disabled) {
    @include _theme-property($config, 'color', text, $variants);
    @include _focus-overlay-color($config, $variants);
  }

  .mat-mdc-flat-button:not(:disabled),
  .mat-mdc-raised-button:not(:disabled),
  .mat-mdc-unelevated-button:not(:disabled),
  .mat-mdc-fab:not(:disabled),
  .mat-mdc-mini-fab:not(:disabled) {
    @include _theme-property($config, 'color', default-contrast, $variants);
    @include _theme-property($config, 'background-color', default, $variants);
    @include _ripple-color($config, default-contrast, $_ripple-opacity, $variants);
  }
}

you should define a scss map object with palettes for success and info:

material-theme-index.scss:

@use './mat-button-variants' as button-variants;

...

$theme-success: mat.define-palette($palette-success);
$theme-info: mat.define-palette($palette-info);

$variants-theme: (
  success: $theme-success,
  info: $theme-info,
);
// and include mixin above
@include button-variants.color($main-theme, $variants-theme);

and now it will work as should in <button mat-raised-button color="success">Click me</button>

PS: if you use material lower versions like 14 and below please rename mdc to mat in classes due to latest breaking changes in material v15 with extra classes prefixes mdc. Current example works for angular 15+.

Lewd answered 2/3, 2023 at 12:37 Comment(4)
And where do the actual colors of info and success get set?Lien
in the _palette.scss file. You need to define a palette for each "color", and next import it to the index file above. that's it. material.angular.io/guide/themingLewd
Fantastic solution @IgorKurkov!! Really thanks! The only thing is in Angular 16, the ripple doesn't take the right color, but is only gray. Anyway really amazing! I imagine this is really difficult to apply to each Material Components ?Tertia
of course, it's a bit tricky, but you can just create a similar file for another component that requires it, like toggle or slider-toggle, and adapt similar code like button-variants.scss for it. generally typography and palette will work with most of the mat-components. ps: however, yeah, ripple/background/foreground need additional effort and customising:)Lewd

© 2022 - 2024 — McMap. All rights reserved.