Angular Materialのカラーパレットをカスタマイズ

カバー

はじめに

当社の文教向けソリューション製品では、フロントエンド開発において主にAngularを採用しています。さらにWebデザインの軸としてマテリアルデザインを取り入れるために、Angular Materialを用いてデザインを定義しています。 本記事ではAngular Materialのカラーテーマについて、開発者が独自で配色カスタマイズするための方法を紹介します。記事内で使用するAngular CLIのバージョンは17.3.2、Angular Materialのバージョンは17.3.1です。またスタイルシートはSCSSで記述します。

マテリアルデザイン・Angular Materialについて

マテリアルデザインとは、Googleが提唱するWebデザインの概念です。画面上のアイテムに影・奥行きなどを持たせる、アイテムのアニメーションに連続性を持たせるなどの要素を持たせることで、直感的なわかりやすさを高めたデザインになっています。
詳細は各バージョンの公式ガイドラインを参照してください。

上記の前提を踏まえて、Angular開発のアプリケーションにマテリアルデザインを適用するためのライブラリが、Angular Materialになります。2024年4月1日時点の最新バージョン17.3.2では、Material Design 2がベースとなっています。
詳細はAngular Materialの公式ガイドラインを参照してください。

Angular Materialを使用するためには、事前にプロジェクトへのインストールが必要です。

Angular Materialのカラーパレット設定方法

パレットとは、画面上における各要素の配色を定義したものです。Angular Materialにおけるパレットは次の5つで構成されています。

  • primary : 画面内でもっとも広く使用される1次色
  • accent : primaryの次に使われる2次色
  • warn : エラー状態などを伝えるために使用される警告色
  • foreground : テキストとアイコンの色
  • background : 画面の背景に使用される色

基本的に、primary, accent, warnには有彩色、foreground, backgroundには白または黒を用います。 今回はprimary, accent, warnにそれぞれ次のコンポーネントを割り当てます。

  • primary : 画面上部のツールバー
  • accent : 画面下部の追加ボタン
  • warn : リスト内のゴミ箱アイコン

デフォルトテーマの設定

Angularのアプリケーションには、あらかじめ定義されたテーマファイルを直接組み込むことができます。テーマファイルにはパレットの配色設定の他に、文字の体裁を決めるtypography、アプリケーション内のコンポーネントのサイズや間隔を決めるdensityの設定も含まれています。

利用可能なテーマファイルは以下の4種類です。

  • indigo-pink.css
  • deeppurple-amber.css
  • pink-bluegrey.css
  • purple-green.css

事前構築済みテーマファイルの導入

デフォルトで構築されているテーマファイルは、2種類の方法で設定できます。

  1. angular.jsonから設定する方法

    AngularプロジェクトにAngular Materialをインストールするタイミングで、テーマファイルのcssが設定可能です。すでにインストール済みの場合でも、インストールをスキップしてテーマファイルの設定を行うことができます。
    プロジェクト配下で以下のコマンドを実行してください。

    $ ng add @angular/material

    実行後に、テーマ選択ができます。今回はindigo-pink.cssを選択します。

    テーマ選択後に表示されるtypographyとanimationの選択に関しては、カラーパレットの設定に影響がないため制限はありません。今回はtypographyの設定にyes、animationの設定に「Include and enable animations」を選択しました。

    実行後、angular.jsonに選択したindigo-pink.cssが追加されているのがわかります。

    {"projects": {
        "projectname": {"architect": {
            "build": {"options": {"styles": [
                  "@angular/material/prebuilt-themes/indigo-pink.css",
                  "src/styles.scss"
                ],},},}
        }
      }
    }
  2. styles.scssから設定する方法

    Angularプロジェクト作成時に定義されているスタイルシートの中でも、テーマファイルを設定できます。styles.scssに以下を追加してください。

    @import '@angular/material/prebuilt-themes/indigo-pink.css';

上記2種類のどちらで適用した場合でも、次のように設定が反映されています。

テーマファイル設定前

テーマファイル設定後

テーマファイル適用の注意

  1. テーマファイル選択のスキップ

    コマンドでテーマファイルを設定する場合、後ろに--themeをつけて実行するとテーマファイルの選択をスキップしてtypographyの選択に入ります。このときテーマファイルは自動的にindigo-pink.cssが適用されます。

    $ ng add @angular/material --theme

    テーマファイルの選択はスキップしつつ、かつテーマファイルを指定する場合は、--themeの後ろに指定するテーマ名を入れてコマンド実行をしてください。

    $ ng add @angular/material --theme=deeppurple-amber
  2. ダークテーマの適用と背景

    前項の手順でpink-bluegrey.css,purple-green.cssといったダークテーマを適用した場合に、背景が白色のままになる場合があります。
    Angular Materialにおいて、background(背景色)の設定はデフォルトで適用されません。これはDOM※の適用範囲にbackgroundが含まれていないためです。 ダークテーマ適用時にbackgroundを有効にするためには、index.htmlのbodyタグに次のクラスを指定してください。

    <body class="mat-app-background">

    ※ DOM(Document Object Model)とは、Webページを階層構造にすることでHTML要素へのアクセスや操作を行えるようにしたもの。Angular Materialの設定もDOMを通して取得している。

独自テーマの設定

テーマファイルは既存テーマの利用だけでなく独自で詳細設定が可能です。
本項では定義されたカラーパレットから配色を割り当てる方法と、独自にカラーコードを指定してパレットを作成する方法について説明します。

マテリアルデザインのカラーパレットを使用

マテリアルデザインには、あらかじめ定義されているカラーパレットが存在します。パレットを指定することで細かな設定が不要なため、簡単にWebデザインのカラーを決めることができます。カラーパレットは色相ごとの種類に分かれており、それぞれのパレット内で明度・彩度の段階が50~900,A100~A700まで割り当てられています。またそれぞれの色相・明度によって適切なコントラストカラーが割り振られています。

Angular Materialでは、Material Designのカラーパレットをベースに独自のカラーパレットを作成しています。詳細は以下を参照してください。

  1. scssの準備

    定義済みパレットやカラーの定義用関数を使用するために、以下を設定するscssファイルに設定してください。

    @use '@angular/material' as mat;
    @use '@angular/material/core/theming/_palette.scss' as theme;
    @include mat.core();
  2. primary, accent, warnをパレットから決定

    デフォルトのテーマファイルには、あらかじめ各要素にどのパレットを使用するのか決定されていました。パレットはデフォルトのテーマファイルに限らず独自テーマでも使用でき、Angular Materialのカラーパレット群から選択します。 今回は以下の3色を使用します。

    • primary : Teal
    • accent : Light Blue
    • warn : Orange

    使用するパレットを決定したら、define-palette関数を使用して先ほどのパレットからdefault,light,darkの3色を定義し、それぞれ割り当てます。 このとき引数にパレットのみを指定する場合は、明度・彩度の段階にそれぞれdefault=500,light=100,dark=700,text=500(defaultと同値)が自動的に割り当てられます。明度・彩度を変更したい場合は、Material Designのカラーパレット群を参照して引数に値を指定します。
    今回はaccentを変更します。

    $custom-primary: mat.define-palette(mat.$teal-palette);
    $custom-accent: mat.define-palette(mat.$light-blue-palette, 700, 100, 900);
    $custom-warn: mat.define-palette(mat.$orange-palette);
  3. テーマをアプリケーションに適用

    primary,accent,warnを定義したら、テーマを作成します。define-light-themeを使用するとライトテーマ、define-dark-themeを使用するとダークテーマになります。
    テーマを適用するために、all-component-themes関数を使用します。定義したテーマを引数に指定します。また先ほど設定したindigo-pink.cssとフォントと同じ設定をtypographyに追加しています。

    以下はライトテーマで適用した場合のコードです。

    $custom-theme: mat.define-light-theme((
      (
        color: (
          primary: $custom-primary,
          accent: $custom-accent,
          warn: $custom-warn,
        ),
        typography: mat.define-typography-config(),
      )
    ));
    
    @include mat.all-component-themes($custom-theme);

    以下は、それぞれのテーマを設定した場合になります。

    ライトテーマ

    ダークテーマ(デフォルトテーマと同じくbackgroundのクラス設定を行う必要があります)

カラーコードを指定した独自パレットを使用

前項では定義されたカラーパレットを使用しましたが、独自でカラーコードを指定してパレットを作成することも可能です。
先ほど適用したprimaryを独自パレットで再設定します。

  1. パレットを作成、定義

    define-palette関数の引数であるdefault,lighter,darkerそれぞれに対しカラーコードを指定します。既存のカラーパレットのルールに則り、defaultを標準色、lighterを明度の高い色、darkを明度に低い色に設定します。 contrastでは、contrast(コンポーネントに表示するテキストやアイコンの色)を指定できます。カラーコードの他に、Angular Materialの_palette.scssで定められたテキストカラーを使用することもできます。 次の設定では、緑色をベースとしたカラーパレット、コントラストには$light-primary-text(#ffffff)を使用しました。

    $custom-palette: (
      default: #0cac07,
      lighter: #72ff6d,
      darker: #036400,
      contrast: (
        default: theme.$light-primary-text,
        lighter: theme.$light-primary-text,
        darker: theme.$light-primary-text,
      ),
    );
    
    $custom-primary: mat.define-palette($custom-palette, default, lighter, darker);

    上記を適用した結果が以下です。ツールバーにdefaultで設定したカラーコード、テキストとアイコンにcontrastの設定が反映されています。

Angular Materialのバージョンと注意点

作成した独自パレットは、前項のツールバーだけでなく他のコンポーネントにも同様に適用できます。しかしAngularのバージョン16までは一部のコンポーネントに対して、独自パレットで定義したコントラストの設定が反映されないことがあります。例として、ボタンやチェックボックスはバージョン16までは独自設定したコントラストは適用されず、ライブラリで自動計算したコントラストが反映されます。
パレット設定時にはAngularのバージョンに注意してカスタマイズしてください。

先行調査 Material Design 3 ベースのカラーパレット

※ このセクションは、2024年4月1日時点でのAngular Materialの先行リリース版について調査した内容になります。今後この情報は変更される可能性があるためご留意ください。

Angular Materialは、2024年4月1日時点の最新バージョン17.3.2でMaterial Design 2をベースとしています。今後リリース予定のバージョンでは、Material Design 3の適用が検討されており、開発が進められています。 バージョンアップに合わせてMaterial Design 3を適用したカラーパレットも追加され、現在は先行してMaterial Design 3用のカラーパレットを使用することが可能です。 先行バージョンのカラーパレットを使用するには、以下をインストールしてください。

$ npm install @angular/material-experimental

現在Material Design 3で定義されているパレット構成は以下になります。Angular Materialでもこの構成に沿ったパレットが構成されています。

  • primary:画面内でもっとも広く使用される1次色
  • secondary:2次色。primaryに同一または隣接する色相で彩度の低い色が採用されています
  • tertiary:3次色。primary,secondaryと調和のとれた色、または対照的でアクセント効果をもたらす色
  • error:エラー状態などを伝えるために使用される警告色。material-experimental内では、あらかじめ赤系統の色でパレットが構成されています
  • surface:背景色や文字・アイコンの色、カードやダイアログといったコンテナーの色が定義されている。無彩色を用いるのが基本

またAngular Material内ではsurfaceを以下の2つに分けてパレットを構成しています。背景色・文字色をそれぞれ調整して決定しています。

  • neutral
  • neutral-variant

パレットの詳細な構成・種類は次のスタイルシートを参照してください。

Material Design 3のテーマおよびカラーパレットを適用

実際にMaterial Design 3のデザイン、カラーパレットを適用します。

  1. テーマ・配色のみを決定

    テーマの定義にはmaterial-experimental内のdefine-theme関数を使用します。現行バージョンとの大きな違いを次に整理しました。

    • define-palette関数でパレットそのものを定義する必要がない
      • どの色を使用するかのみを設定し、明暗やコントラストなどの調整は自動で行われます
    • 指定する有彩色のパレットが2つ
      • パレット構成内の有彩色は4つですが、自由に割り当てられる色はprimary,tertiaryの2色のみです
    • テーマ定義の関数が分かれていない
      • 関数内でライトテーマまたはダークテーマを設定できます

    define-theme関数で定義できるcolorの設定は次の3つになります。

    • theme-type
      • light(ライトテーマ)またはdark(ダークテーマ)のどちらかを指定する
      • 指定しない場合は自動でライトテーマが適用される
    • primary
      • 1次色パレットの指定
      • 同時にprimaryと調和のとれたsecondary,neutral,neutral-variantが自動で選択されます
    • tertiary
      • 3次色パレットの指定

    以下はdefine-theme関数で定義した際のコードです。html内に対してall-component-themes関数を用いて全適用を行うことで、画面全体に統一テーマを適用できます。

    @use '@angular/material' as mat;
    @use '@angular/material-experimental' as matx;
    @include mat.core();
    
    $custom-theme: matx.define-theme((
      color: (
        theme-type: light,
        primary: matx.$m3-azure-palette,
        tertiary: matx.$m3-violet-palette,
      ),
    ));
    
    html {
      @include mat.all-component-themes($custom-theme);
    }

    以下は、ライトテーマ、ダークテーマそれぞれで設定した場合になります。
    明暗の差によって、背景色や文字色だけでなくアイコンやボタンの色にも自動調整が入っています。

    ライトテーマ

    ダークテーマ

    このとき、追加ボタンにはprimaryで設定したAzureパレット、ゴミ箱ボタンにはsurfaceのパレットから自動で配色されています。またツールバーにはこれまで適用されていたprimaryのパレットが適用されなくなりました。 現行バージョンまではコンポーネントそれぞれにどのパレットから割り当てるのか決めていたのに対し、次バージョンではあらかじめどのコンポーネントにどのパレットを使用するのかが定められています。
    コンポーネントとパレットの割り当てについての対応表は、以下の公式ドキュメントを参照してください。

  2. コンポーネントごとに使用する配色を指定

    前項ではコンポーネントごとに使用する色が自動で割り当たっていましたが、コンポーネントの種別やクラス名を指定することでどの色を使用するか独自で設定することもできます。 今回は追加ボタンにVioletパレットを設定したtertiary、ゴミ箱ボタンに警告色のerrorを適用します。
    クラス名を指定し、配色定義の関数に使用テーマと使用するパレット名を設定します。

    .fab-button {
      @include mat.fab-color($custom-theme, $color-variant: tertiary);
    }
    
    .delete-icon{
      @include mat.icon-color($custom-theme, $color-variant: error);
    }

    上記を適用すると、以下のように追加ボタンとゴミ箱ボタンが設定した内容で反映されています。

    ライトテーマ

    ダークテーマ

  3. コンポーネント自体のテーマを変更する

    明暗のテーマを統一すると、それに合わせて配色の割り当てもルールに従ったものになります。
    全体はこのテーマにしたいが特定のコンポーネントには別テーマを使用したい、という場合には別テーマの設定を用意しそれを適用させることができます。 以下のコードでは、全体は前項のライトテーマを適用しつつ、ダークテーマとprimaryにChartreuseパレットを割り当てた新規テーマを用意し、追加ボタンに割り当てました。

    $custom-theme: matx.define-theme((
      color: (
        theme-type: light,
        primary: matx.$m3-azure-palette,
        tertiary: matx.$m3-violet-palette,
      ),
    ));
    
    $button-theme: matx.define-theme((
      color: (
        theme-type: dark,
        primary: matx.$m3-chartreuse-palette,
        tertiary: matx.$m3-violet-palette,
      ),
    ));
    
    .fab-button {
      @include mat.fab-color($button-theme);
    }

    追加したテーマをボタンに割り当てると、次のように表示されます。

今後リリースされるバージョンでは、設定方法や仕様に変更や追加が入ることが予測されます。これからのアップデートに期待ですね。

おわりに

本記事ではAngularにおけるマテリアルデザインの独自カラーパレット設定について紹介しました。
Angularで開発をされている方の一助になれば幸いです。

参考


TOP
アルファロゴ 株式会社アルファシステムズは、ITサービス事業を展開しています。このブログでは、技術的な取り組みを紹介しています。X(旧Twitter)で更新通知をしています。