Angular Material でカスタムカラーを使う
Angular Advent Calendar 2021 15 日目の記事です。
Angular Material を使う場合、デフォルトで下記のテーマが用意されています。
- Deep Purple & Amber
- Indigo & Pink
- Pink & Blue-gray
- Purple & Green
しかし、これらのカラーテーマをそのまま使うことってほとんどないですよね。コーポレートカラーやアプリケーションのイメージカラーが Material Design のカラーパレットに含まれる色だった場合はラッキーですが、なかなかそうもいきません。
今回は Angular Material における色の管理方法を交えながら、カスタムカラーを使う方法をご紹介します。
各 version
- Angular: v13.0.0
- Angular Material: v13.0.3
Angular Material で用意されている色の定義を見てみよう
Angular Material では こちらの_palette.scss で管理されています。
40 行目$red-paletter
の定義を見てみましょう。
$red-palette: (
50: #ffebee,
100: #ffcdd2,
200: #ef9a9a,
300: #e57373,
400: #ef5350,
500: #f44336,
600: #e53935,
700: #d32f2f,
800: #c62828,
900: #b71c1c,
A100: #ff8a80,
A200: #ff5252,
A400: #ff1744,
A700: #d50000,
contrast: (
50: $dark-primary-text,
100: $dark-primary-text,
200: $dark-primary-text,
300: $dark-primary-text,
400: $dark-primary-text,
500: $light-primary-text,
600: $light-primary-text,
700: $light-primary-text,
800: $light-primary-text,
900: $light-primary-text,
A100: $dark-primary-text,
A200: $light-primary-text,
A400: $light-primary-text,
A700: $light-primary-text,
)
);
こちらのコードは Material Design のカラーパレットを表しています。
red-palette
直下では 50〜A700 までのカラーコードを、contract
の中では 50〜A700 までのカラーが背景になったときの文字色を定義しています。カラーコードの中で 50〜900 は通常色、A100〜A700 はアクセントカラーとして使うことを想定されいてる色のようで、通常色に比べてビビットな色が定義されています。
文字色はこちらのTypography のガイドライン に沿い、文字の視認性を考慮して不透明度 87% の黒か不透明度 100%の白が指定されています。
カスタムカラーのパレットを用意する
カスタムカラーを使用したい場合は、前項で紹介したのと同じようなパレットの scss 変数を用意してあげる必要があります。色の知識なしにパレットを作成するのは難しいですが、Material Design に沿ったカラーパレットを生成してくれる Web サービスがありますのでご安心ください。
こちらのMaterial Design Palette Generatorを使用することで、簡単にカラーパレットを生成できます。
右上の青い四角をクリックして、基準となる 500 に設定したい色を指定します。その後クリップボードのアイコンをクリックして、ANGULAR JS 2 (MATERIAL2)
を選ぶと、先程見た$red-palette
のようなパレットのコードを生成してくれています。
カスタムカラーに変更してみる
早速こちらを設定してみましょう。
既存の theme css を削除する
まずng add
したときに Deep Purple & Amber 等のテーマを指定した場合は、angular.json
からそのテーマ用の css を削除します。対象の project のbuild
とtest
に記述があるので、それぞれ削除しましょう。
"styles": [
- "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/style.scss"
],
custom palette を作成する
Material Design Palette Generator で生成したコードを使って custom palette を作成しましょう。
今回は 500 に#f1e332
(黄色)を指定して作ってみました。
$custom-primary: (
50: #fdfce6,
100: #fbf7c2,
200: #f8f199,
// ...A700まで
contrast:
(
50: #000000,
100: #000000,
200: #000000,
// ...A700まで
)
);
Color Theme を設定する
styles.scss に下記のように追記します。
@use "@angular/material" as mat;
@use "./assets/palette" as palette;
@include mat.core();
// primary に先程作成した $custom-primary を指定
$custom-primary: mat.define-palette(palette.$custom-primary);
// secondary はAngular Material のpalette からlight-blue を指定
$custom-accent: mat.define-palette(mat.$light-blue-palette, A200, A100, A400);
$custom-warn: mat.define-palette(mat.$red-palette);
$custom-theme: mat.define-light-theme(
(
color: (
primary: $custom-primary,
accent: $custom-accent,
warn: $custom-warn,
),
)
);
@include mat.all-component-themes($custom-theme);
mat.define-palette()
の実装を見てみましょう。
@function define-palette($base-palette, $default: 500, $lighter: 100, $darker: 700,
$text: $default) {
$result: map.merge($base-palette, (
default: map.get($base-palette, $default),
lighter: map.get($base-palette, $lighter),
darker: map.get($base-palette, $darker),
text: map.get($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)
));
// 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)
));
}
@return $result;
}
引数にカラーパレットとその中でデフォルトの色・デフォルトの色の明るいバージョンと暗いバージョン・テキストの色がありますが、それぞれにデフォルト値が設定されています。なので先程設定した$custom-primary
は引数が 1 つで十分ですが、アクセントカラーを使う$custom-accent
では引数として 3 色渡しています。
// 自動で500, 100, 700 が使われる
$custom-primary: mat.define-palette(palette.$custom-primary);
// 500, 100, 700 以外のアクセントカラーを使いたいので3つ指定する
$custom-accent: mat.define-palette(mat.$light-blue-palette, A200, A100, A400);
これでカスタムカラーを指定することができました!結果を見てみましょう!
MATCH みたいな爽やかな色合いになりましたね!Angular Material を使う以上は Material Design のカラーパレットを使うに越したことはありませんが、別の色を使う必要がある場合はこのように設定して実装していきましょう!
Discussion