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

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


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さんの記事です.

よろしくお願いいたします.

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)