blog

SCSSでカラーコードを管理する関数を作る

    • Ryuichi Nonaka
    この記事は書かれてから1年以上経過しており、内容が古い場合があります。

    はじめに

    関数といってもとても簡単なもので配列で管理したカラーコードをmap-get()で取得します。色の変更も容易になり、管理しやすくなります。

    関数の定義

    5行だけ、とっても簡単。

    @function palette( $palette_name, $tone_name: 'base' ) {
      $palette: map-get( $palettes, $palette_name );
      $torn:    map-get( $palette, $tone_name );
      @return $torn;
    }
    

    カラーコード

    カラーコードは$palettesに定義します。
    配列でグループ名を定義して連想配列で色名とカラーコードを指定します。baseがデフォルト値です。

    $palettes: (
      'typo': (
        'base': #444,
        'inverse': #eee
      ),
      'anchor': (
        'base': #82baff,
        'inverse': #9ae7f0
      ),
      'bg': (
        'base': #242b33,
        'dark': #131519,
        'light': #374251,
        'inverse': #fafafa
      )
    );
    

    使う

    引数にグループ名(必須)、色名(オプション)を指定します。

    div {
      background: palette( 'bg' );
    }
    

    CSSは以下のようになります。

    div {
      background: #242b33;
    }
    

    色名を指定した場合

    第2引数に色名を指定します。

    div {
      background: palette( 'bg', 'inverse' );
    }
    

    CSSは以下のようになります。

    div {
      background: #fafafa;
    }
    

    第3引数にdarkenやlightenを指定できるようにして、指定色から少し暗い、明るい色も取得できるようになるとシャドウやボーダー指定に便利かもしれません。

    おまけ

    HSBでHueを基準にしたカラーパレットを作ったけど、それほど使い勝手も良くなかった。とりあえず参考資料として載せておきます。HSBへの変換とかブレンドモード、アルファ指定ができるので、こっちの方が高機能です。

    関数(hsb_palette)

    HSVへの変換はhsvtohsl.scssを参考にしています。

    @function hsb_palette( $palette_name, $tone_name: 'base', $blending: 'normal', $degree: 0, $alpha: 1.0 ) {
      //get torn
      $palette: map-get( $hsb_palettes, $palette_name );
      $torns:   map-get( $palette, 'torn' );
      $torn:    map-get( $torns, $tone_name );
    
      //get hsb
      $hue: map-get( $palette, 'hue' );
      $saturation: map-get( $torn, 's' );
      $brightness: map-get( $torn, 'b' );
    
      //blending
      @if $blending == 'burn' {
        $saturation: $saturation + $degree;
        $brightness: $brightness - $degree;
      } @else if $blending == 'dodge' {
        $saturation: $saturation - $degree;
        $brightness: $brightness + $degree;
      } @else if $blending == 'desaturate' {
        $saturation: $saturation - $degree;
      } @else if $blending == 'saturate' {
        $saturation: $saturation + $degree;
      } @else if $blending == 'lighten' {
        $brightness: $brightness + $degree;
      } @else if $blending == 'darken' {
        $brightness: $brightness - $degree;
      }
    
      //round
      @if $saturation > 100% {
        $saturation: 100%;
      } @else if $saturation < 0% {
        $saturation: 0%;
      }
    
      @if $brightness > 100% {
        $brightness: 100%;
      } @else if $brightness < 0% {
        $brightness: 0%;
      }
    
      //convert hsl
      $hsl: hsb_to_hsl( $hue, $saturation, $brightness );
      @return hsla( nth($hsl, 1), nth($hsl, 2), nth($hsl, 3), $alpha);
    }
    
    
    @function hsb_to_hsl($h, $s: 0, $b: 0) {
      @if type_of($h) == 'list' {
        $b: nth($h, 3);
        $s: nth($h, 2);
        $h: nth($h, 1);
      }
    
      @if unit($h) == 'deg' {
        $h: 3.1415 * 2 * ($h / 360deg);
      }
      @if unit($s) == '%' {
        $s: 0 + ($s / 100%);
      }
      @if unit($b) == '%' {
        $b: 0 + ($b / 100%);
      }
    
      $ss: $s * $b;
      $ll: (2 - $s) * $b;
    
      @if $ll <= 1 {
        $ss: $ss / $ll;
      } @else if ($ll == 2) {
        $ss: 0;
      } @else {
        $ss: $ss / (2 - $ll);
      }
    
      $ll: $ll / 2;
    
      @return 360deg * $h / (3.1415 * 2), percentage(max(0, min(1, $ss))), percentage(max(0, min(1, $ll)));
    }
    

    カラーパレット

    /* 
    
    $hsb_palettes: (
      'name': (
        hue : 0deg,
        torn: (
          '2x-light'  : ( s: 0%, b: 10% ),
          'x-light'   : ( s: 0%, b: 10% ),
          'light'     : ( s: 0%, b: 10% ),
          'mid-light' : ( s: 0%, b: 10% ),
          'base'      : ( s: 0%, b: 10% ),
          'mid-dark'  : ( s: 0%, b: 10% ),
          'dark'      : ( s: 0%, b: 10% ),
          'x-dark'    : ( s: 0%, b: 10% ),
          '2x-dark'   : ( s: 0%, b: 10% )
        )
      ),
    */
    
    $hsb_palettes: (
      'mono': (
        hue : 0deg,
        torn: (
          '2x-light'  : ( s: 0%, b: 95% ),
          'x-light'   : ( s: 0%, b: 85% ),
          'light'     : ( s: 0%, b: 70% ),
          'mid-light' : ( s: 0%, b: 60% ),
          'base'      : ( s: 0%, b: 50% ),
          'mid-dark'  : ( s: 0%, b: 40% ),
          'dark'      : ( s: 0%, b: 30% ),
          'x-dark'    : ( s: 0%, b: 15% ),
          '2x-dark'   : ( s: 0%, b:  5% )
        )
      ),
      'bg': (
        hue : 210deg,
        torn: (
          'asphalt'   : ( s: 45%, b: 37% ),
          'midnight'  : ( s: 45%, b: 31% ),
          'dark'      : ( s: 45%, b: 25% )
        )
      ),
      'board': (
        hue : 192deg,
        torn: (
          'cloud'    : ( s:  2%, b: 95% ),
          'silver'   : ( s:  5%, b: 78% ),
          'concrete' : ( s: 10%, b: 65% ),
          'asbestos' : ( s: 10%, b: 55% )
        )
      ),
      'red': (
        hue : 6deg,
        torn: (
          'base' : ( s: 74%, b: 91% )
        )
      ),
      'orange': (
        hue : 32deg,
        torn: (
          'base' : ( s: 79%, b: 95% )
        )
      ),
      'yellow': (
        hue : 47deg,
        torn: (
          'base' : ( s: 94%, b: 95% )
        )
      ),
      'lime': (
        hue : 85deg,
        torn: (
          'base' : ( s: 75%, b: 87% )
        )
      ),
      'green': (
        hue : 138deg,
        torn: (
          'base' : ( s: 76%, b: 83% )
        )
      ),
      'emerald': (
        hue : 161deg,
        torn: (
          'base' : ( s: 78%, b: 87% )
        )
      ),
      'cyan': (
        hue : 186deg,
        torn: (
          'base' : ( s: 76%, b: 88% )
        )
      ),
      'aqua': (
        hue : 202deg,
        torn: (
          'base' : ( s: 68%, b: 89% )
        )
      ),
      'blue': (
        hue : 219deg,
        torn: (
          'base' : ( s: 71%, b: 89% )
        )
      ),
      'deepblue': (
        hue : 234deg,
        torn: (
          'base' : ( s: 70%, b: 84% )
        )
      ),
      'violet': (
        hue : 268deg,
        torn: (
          'base' : ( s: 72%, b: 88% )
        )
      ),
      'purple': (
        hue : 288deg,
        torn: (
          'base' : ( s: 65%, b: 88% )
        )
      ),
      'winered': (
        hue : 340deg,
        torn: (
          'base' : ( s: 69%, b: 92% )
        )
      ),
    );
    

    以上、SCSSを使ったカラーコードの管理でした。

    コメント・フィードバック