Understanding the Angular Material define-palette SASS Function

Ole Ersoy
3 min readMay 27, 2022
Image by Roland Steinmann from Pixabay

Scenario

We would like a breakdown of the result of applying the define-palette function (Formerly mat-palette ) as follows.

$theme-accent: mat.define-palette(mat.$cyan-palette);

Approach

The mat.$cyan-palette color palette contains a SASS map with hue key to color values. The hue keys range from 50 to 900, with the addition of the accent colors A100, A200, A400, and A700 .

In addition it contains a nestedcontrast map that has the same range of hue keys. Running @debug mat.#cyan-palette reveals the following.

( 50: #e0f7fa, 
100: #b2ebf2,
200: #80deea,
300: #4dd0e1,
400: #26c6da,
500: #00bcd4,
600: #00acc1,
700: #0097a7,
800: #00838f,
900: #006064,
A100: #84ffff,
A200: #18ffff,
A400: #00e5ff,
A700: #00b8d4,
contrast: (
50: rgba(0, 0, 0, 0.87),
100: rgba(0, 0, 0, 0.87),
200: rgba(0, 0, 0, 0.87),
300: rgba(0, 0, 0, 0.87),
400: rgba(0, 0, 0, 0.87),
500: white,
600: white,
700: white,
800: white,
900: white,
A100: rgba(0, 0, 0, 0.87),
A200: rgba(0, 0, 0, 0.87),
A400: rgba(0, 0, 0, 0.87),
A700: rgba(0, 0, 0, 0.87)))

If we @debug $theme-accent we see that it contains.

( 50: #e0f7fa, 
100: #b2ebf2,
200: #80deea,
300: #4dd0e1,
400: #26c6da,
500: #00bcd4,
600: #00acc1,
700: #0097a7,
800: #00838f,
900: #006064,
A100: #84ffff,
A200: #18ffff,
A400: #00e5ff,
A700: #00b8d4,
contrast: (
50: rgba(0, 0, 0, 0.87),
100: rgba(0, 0, 0, 0.87),
200: rgba(0, 0, 0, 0.87),
300: rgba(0, 0, 0, 0.87),
400: rgba(0, 0, 0, 0.87),
500: white,
600: white,
700: white,
800: white,
900: white,
A100: rgba(0, 0, 0, 0.87),
A200: rgba(0, 0, 0, 0.87),
A400: rgba(0, 0, 0, 0.87),
A700: rgba(0, 0, 0, 0.87)))
default: #00bcd4,
lighter: #b2ebf2,
darker: #0097a7,
text: #00bcd4,
default-contrast: white,
lighter-contrast: rgba(0, 0, 0, 0.87),
darker-contrast: white,
"50-contrast": rgba(0, 0, 0, 0.87),
"100-contrast": rgba(0, 0, 0, 0.87),
"200-contrast": rgba(0, 0, 0, 0.87),
"300-contrast": rgba(0, 0, 0, 0.87),
"400-contrast": rgba(0, 0, 0, 0.87),
"500-contrast": white,
"600-contrast": white,
"700-contrast": white,
"800-contrast": white,
"900-contrast": white,
"A100-contrast": rgba(0, 0, 0, 0.87),
"A200-contrast": rgba(0, 0, 0, 0.87),
"A400-contrast": rgba(0, 0, 0, 0.87),
"A700-contrast": rgba(0, 0, 0, 0.87),
"contrast-contrast": null)

To understand how this result was generated lets have a look at the source code for define-palette .

So the define-palette function takes the a material color palette along with the default , lighter , darker , and text hue key values and uses these to augment the passed in color palette with additional values.

The block.

$result: map.merge($base-palette, (    default: _get-color-from-palette($base-palette, $default),    lighter: _get-color-from-palette($base-palette, $lighter),    darker: _get-color-from-palette($base-palette, $darker),    text: _get-color-from-palette($base-palette, $text),     default-contrast: get-contrast-color-from-palette($base-palette, $default),    lighter-contrast: get-contrast-color-from-palette($base-palette, $lighter),    darker-contrast: get-contrast-color-from-palette($base-palette, $darker)  ));

Merges in color values for the default , lighter , darker , and text keys, as well as the corresponding contrast values for these.

The block.

// For each hue in the palette, add a "-contrast" color to the map.  @each $hue, $color in $base-palette {    $result: map.merge($result, (      '#{$hue}-contrast': get-contrast-color-from-palette($base-palette, $hue)    ));  }

Gives us access to the contrast values contained in the nested contrast map within the main map. Each constrast key is postfixed with -contrast .

This new augmented palette can be used with Angular Materials get-color-from-palette function to retrieve color values.

@use '@angular/material' as mat;

body {
height: 100%;
background-color: mat.get-color-from-palette($theme-accent, default);
color: mat.get-color-from-palette($theme-accent, default-contrast);
}

Playground

The below Stackblitz Web Container can be used to play with the SCSS capabilities of Angular.

--

--