SASS-only Material Angular 2 Palette generator (2025 Update)

This is an updated version of my old article SASS-only Material Angular Palette generator published in 2020. It’s updated to be compatible with Angular 18+ and Material 2.

mat-palette-gen.scss
@use 'sass:math';
@use 'sass:map';
@use 'sass:color';

$values: (50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400, A700);

@mixin _output-palette-variables($map, $prefix) {
  @each $key, $value in $map {
    @if ($value) {
      @if ($key == 'contrast') {
        @include _output-palette-variables($value, '#{$prefix}-contrast');
      } @else {
        --#{$prefix}-#{$key}: #{$value};
      }
    }
  }
}

@function createPalette($color) {

  $white: #fff;
  $black: #000;
  $baseDark: multiply($color, $color);

  $palette: (
    50 : color.mix($color, $white, 12%),
    100 : color.mix($color, $white, 30%),
    200 : color.mix($color, $white, 50%),
    300 : color.mix($color, $white, 70%),
    400 : color.mix($color, $white, 85%),
    500 : color.mix($color, $white, 100%),
    600 : color.mix($color, $baseDark, 87%),
    700 : color.mix($color, $baseDark, 70%),
    800 : color.mix($color, $baseDark, 54%),
    900 : color.mix($color, $baseDark, 25%),
    A100: color.adjust(color.mix($black, $baseDark, 15%), $lightness: 65%, $saturation: 80%),
    A200: color.adjust(color.mix($black, $baseDark, 15%), $lightness: 55%, $saturation: 80%),
    A400: color.adjust(color.mix($black, $baseDark, 15%), $lightness: 45%, $saturation: 100%),
    A700: color.adjust(color.mix($black, $baseDark, 15%), $lightness: 40%, $saturation: 100%),
  );

  $contrast: ();
  @each $v in $values {
    $contrast: map.merge($contrast, ($v: getContrast(map.get($palette, $v))))
  }

  $palette: map.merge($palette, (contrast: $contrast));

  @return $palette;
}


@function multiply($rgb1, $rgb2) {
  $r: math.floor(math.div(color.channel($rgb1, "red", $space: rgb) * color.channel($rgb2, "red", $space: rgb), 255));
  $g: math.floor(math.div(color.channel($rgb1, "green", $space: rgb) * color.channel($rgb2, "green", $space: rgb), 255));
  $b: math.floor(math.div(color.channel($rgb1, "blue", $space: rgb) * color.channel($rgb2, "blue", $space: rgb), 255));
  @return rgb($r, $g, $b);
}

@function getBrightness($color) {
  @return math.div(color.channel($color, "red", $space: rgb) * 299 + color.channel($color, "green", $space: rgb) * 587 + color.channel($color, "blue", $space: rgb) * 114, 1000);
}

@function isLight($color) {
  @return getBrightness($color) >= 128;
}

@function getContrast($color) {
  @if isLight($color) {
    @return #000;
  } @else {
    @return #fff;
  }
}

Read more