21
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularAdvent Calendar 2018

Day 10

Angular+sass(scss)によるカラーテーマ切り替えベストプラクティス

Last updated at Posted at 2018-12-09

Angular+sass(scss)によるカラーテーマ切り替えベストプラクティス

https___angular-changetheme.stackblitz.io-Google-Chrome-2018_12_09-19_27_33.gif

この記事は,Angular Advent Calendar 2018,10日目の記事です.

TL;DR

目指したかったもの

  • WEBで,各要素の色を,瞬時に切り替えたい
  • 全部css(sass,もといscss)で管理したい
  • 色は,scssの変数で1か所で管理したい
  • このご時世にaddClassとか,removeClassとかしたくない…….
  • 各要素ごとに,テーマごとのcssを全部定義するのも,メンテできなくなるのでしたくない.
  • 結論,テーマごとに定義した色変数を用いて,それをスマートに切り替えてくれるもの

執筆動機

  • 上記要件を満たした実装が,検索してもでてこなかった
  • よくあるのは,要素ごとに色を定義して,上位クラス(wrapperとか)のクラスをremoveClass,addClassで付け替えることによる切り替え例.
  • もっとスマートにできるはず,かつ色も変数化できるはず,と頭を悩ませて,一応落としどころを見つけたので共有したい.

考えた構成

  • 1,Wrapperクラスを,テーマ分生成する.ただし,色の定義は1回のみとする.
    image.png

  • 2,Wrapperクラスを,Angularのバインドによって切り替える.
    image.png

コード解説

  • 1,Wrapperクラスを,テーマ分生成する.ただし,色の定義は1回のみとする.
// 適当な値で変数を初期化しておく
$back: #000000;
$font: #000000;
$bttn: #000000;
$btnf: #000000;

// テーマの数だけループする
@for $i from 1 through 2 {

  .wrapper#{$i} {
    @if $i == 1 {
        // テーマごとに色を定義する,1回で良い.
        $back : #F4F3EE;
        $font : #463F3A;
        $bttn : #E0AFA0;
        $btnf : #FFFFFF;
    } @else {
        $back : #000000;
        $font : #FFFFFF;
        $bttn : #32FFFB;
        $btnf : #38005B;
    }

    // スタイリングは,テーマごとに切り替えなくてよい.
    background-color: $back;
    color: $font;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;

    .block{
      padding: 20px;
      h1 {
        font-size: 24px;
        padding: 0;
        margin: 0;
      }
      button {
        background-color: $bttn;
        color: $btnf;
      }
    }
  }
}

  • 2,Wrapperクラスを,Angularのバインドによって切り替える.

.html

<!-- クラス名をバインドしている -->
<div [(class)]="colorTheme">
  <div class="block">
    <h1>Change Color Theme with .scss and .ts</h1>
    <p>
      toggle and change theme :)
    </p>
  </div>
  <div class="block">
    <button mat-button>This is the Button</button>
  </div>
  <div class="block">
    <mat-slide-toggle (change)="changeColor($event)">
        On Dark
    </mat-slide-toggle>    
  </div>
</div>

.ts


import { Component } from '@angular/core';
import { MatSlideToggle } from '@angular/material';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.scss' ]
})
export class AppComponent  {
  name = 'Angular';

  // バインドするテーマ
  public colorTheme = 'wrapper1';

  constructor(){
    this.colorTheme = 'wrapper1';
  }

  // toggle event
  // トグルされるたびに,バインドするクラス名を変更する
  public changeColor(e){
    if(e.checked) {
      // to dark
      this.colorTheme = 'wrapper2';
    } else {
      // to light
      this.colorTheme = 'wrapper1';
    }
  }
}

終わりに

  • この仕組みの優れたポイントは,色の定義を1極集中管理しながら,色の切り替えが行えるところである.
  • とはいえラッパーの切り替えや,scssのループなどは決して可読性は高くないので,もう少し改良ができればしたい.

明日は@kimamulaさんの記事です.
よろしくお願いいたします.

21
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?