Angular+sass(scss)によるカラーテーマ切り替えベストプラクティス
この記事は,Angular Advent Calendar 2018,10日目の記事です.
TL;DR
目指したかったもの
- WEBで,各要素の色を,瞬時に切り替えたい
- 全部css(sass,もといscss)で管理したい
- 色は,scssの変数で1か所で管理したい
- このご時世にaddClassとか,removeClassとかしたくない…….
- 各要素ごとに,テーマごとのcssを全部定義するのも,メンテできなくなるのでしたくない.
- 結論,テーマごとに定義した色変数を用いて,それをスマートに切り替えてくれるもの
執筆動機
- 上記要件を満たした実装が,検索してもでてこなかった
- よくあるのは,要素ごとに色を定義して,上位クラス(wrapperとか)のクラスをremoveClass,addClassで付け替えることによる切り替え例.
- もっとスマートにできるはず,かつ色も変数化できるはず,と頭を悩ませて,一応落としどころを見つけたので共有したい.
考えた構成
コード解説
- 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さんの記事です.
よろしくお願いいたします.