noxi雑記

.NET、Angularまわりの小ネタブログ

Angular Materialのテーマカラーをカスタマイズする

Angular MaterialはAngular公式のマテリアルデザインコンポーネントライブラリです。このライブラリのテーマカスタマイズ方法は公式ドキュメントにも記載がされています。

material.angular.io

ドキュメントにはマテリアルデザイン標準?のテーマパレットを使用したカスタマイズ方法が記載されています。この記事は標準のカラーパレットを使用しない、独自テーマの実装方法についてのメモです。


環境

Angular CLI: 8.0.4
Node: 10.16.0
OS: darwin x64
Angular: 8.0.2
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.4
@angular-devkit/build-angular     0.800.4
@angular-devkit/build-optimizer   0.800.4
@angular-devkit/build-webpack     0.800.4
@angular-devkit/core              8.0.4
@angular-devkit/schematics        8.0.4
@angular/cdk                      8.0.1
@angular/cli                      8.0.4
@angular/material                 8.0.1
@ngtools/webpack                  8.0.4
@schematics/angular               8.0.4
@schematics/update                0.800.4
rxjs                              6.4.0
typescript                        3.4.5
webpack                           4.30.0

ng new して ng add @angular/material しただけの環境です。Angular Materialのインストールオプションはテーマを custom に設定しています。

下準備

インストール初期状態のSCSS

環境セクションにもあるとおり、AngularとAngular Materialをインストールします。

ng new angular-material-color-sample
cd angular-material-color-sample
ng add @angular/material

theme: custom でインストールすると styles.scss ファイルが更新されます。だいたいこんな感じです。

// src/styles.scss

// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@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/
$app-theme-primary: mat-palette($mat-indigo);
$app-theme-accent: mat-palette($mat-pink, A200, A100, A400);

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

// Create the theme object (a Sass map containing all of the palettes).
$app-theme: mat-light-theme($app-theme-primary, $app-theme-accent, $app-theme-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($app-theme);

/* You can add global styles to this file, and also import other style files */

html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }

ざっくりとした処理の流れはPrimaryとAccent、Warnとする色を選択してカラーパレットマップを mat-palette で生成し、 mat-light-theme で背景色や文字色などを含んだアプリテーママップを生成します。アプリテーママップ生成は背景色が白のものは mat-light-theme を、背景色が黒のものは math-dark-theme を使用します。

カラーパレットの構造

テーマをカスタマイズするにはカラーパレットの構造を知る必要があります。Angular Materialのカラーパレットはその色の色階層と色階層毎の文字色(contrast)が定義されています。例えば組み込みされているIndigoパレットでは、50・100・200の文字色が黒、300以上だと白、と定義されています。

$dark-primary-text: rgba(black, 0.87);
$light-primary-text: white;

$mat-indigo: (
  50: #e8eaf6,
  100: #c5cae9,
  200: #9fa8da,
  300: #7986cb,
  400: #5c6bc0,
  500: #3f51b5,
  600: #3949ab,
  700: #303f9f,
  800: #283593,
  900: #1a237e,
  A100: #8c9eff,
  A200: #536dfe,
  A400: #3d5afe,
  A700: #304ffe,
  contrast: (
    50: $dark-primary-text,
    100: $dark-primary-text,
    200: $dark-primary-text,
    300: $light-primary-text,
    400: $light-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,
  )
);

テーマのカスタマイズ

テーマカラーを選択する

アプリテーマを作成するにはまずPrimaryとAccent、Warnの3色を選びます。マテリアルデザインのカラーツールを使用しましょう。

material.io

テーマカラーをどう選択するかはさておき、このカラーツールを使用すると選択した色に対応するちょっと明るい色・暗い色と文字色が分かります。Indigo-500をプライマリーカラーに選択すると、Indigo-500に対応する明るい色や暗い色、および選択するべき文字の色がAccessibilityタブに表示されます。選択する色は標準パレット以外にもカラーピッカーやRGB値入力ができます。

f:id:noxi515:20190626211048p:plain
Indigo 500選択時

プライマリーカラーとアクセントカラーの組み合わせをこのカラーツールに入力してそれぞれの明るい色と暗い色、文字色を取得します。なお、色の組み合わせ自体を作成するのは別のツールで行うことをお勧めします。
プライマリーカラーにIndigo-500、アクセントカラーにPink-A200を選択したときのそれぞれの色は次の表となります。絶対にこのツールで表示された値を使わねばならぬということはなく、目安として使用しましょう。

種別 メイン 明るい 暗い
プライマリー
#3f51b5
#757de8
#002984
アクセント
#ff4081
#ff79b0
#c60055

アプリテーマの作成

カラーツールで選択した色を元にしてアプリテーマを実装します。Angular Materialインストール時に自動で編集された styles.scss にて、標準のカラーパレットを独自のカラーパレットに差し替えれば完了です。

$primary-palette: (
  default: #3f51b5,
  darker: #002984,
  lighter: #757de8,
  contrast: (
    default: $light-primary-text,
    darker: $light-primary-text,
    lighter: $dark-primary-text,
  )
);
$accent-palette: (
  default: #ff4081,
  darker: #c60055,
  lighter: #ff79b0,
  contrast: (
    default: $dark-primary-text,
    darker: $light-primary-text,
    lighter: $dark-primary-text,
  )
);

$primary: mat-palette($primary-palette, default, darker, lighter);
$accent: mat-palette($accent-palette, default, darker, lighter);
$warning: mat-palette($mat-red);

$app-theme: mat-light-theme($primary, $accent, $warning);