BLOG

SCSSでできること

ひらの

お久しぶりです、ブログに登場するのは数年ぶりになります。
ひらのです。

久々のブログは「SCSS」について…

もうCSSをごちゃごちゃ色々書きたくない…
CSSをもっと早く書きたい…

そんな事を思ったら、 SCSS がおススメです。

SCSSで何する

SASS(SCSS)は、CSSを効率的に記述できるように設計・開発されたメタ言語。

SASS(SCSS)をコンパイルすることでCSSを生成することができます。

SASS(SCSS)の良い点は…

  • 記述量が減る
  • 後々の修正が楽
  • 便利な機能がいっぱい

SCSSに馴れるとCSS手で書く日々には戻れなくなると思います。

SASS と SCSS

https://sass-lang.com/

SASS とSCSS は名前が違いますが、やりたいことは同じ。

これらの違いは書き方

SASSに比べてSCSSは書き方がCSSに近いので、
普段CSSを書きなれている方はSCSSの方が馴染みやすいと思います。

今回はそんなSCSSの便利な書き方についてご紹介します。

基本的な書き方

SCSSを記述(左)し、コンパイルするとCSS(右)のようになります。

scss

.foo {
  color: blue;
  .bar {
    color: red;
  }
}

css

.foo {
  color: blue;
}
.foo .bar {
  color: red;
}

まず、SCSSはネスト構造で記述します。(入れ子状態)

通常の書き方では、ネストしたセレクタは
コンパイル後、セレクタを継承して記述されます。

scss

a {
  &:hover {
    color: pink;
  }
}

css

a:hover {
  color: pink;
}

ネスト時に「&」でセレクタ(Class名)を記述すると、スペースなどが入らずに連続したセレクタとして記述することができます。

変数

変数は「“`$〇〇“`」という形で先に値を設定してお行きます。
値を使う箇所に変数名を記述すると、コンパイル時に値が入ります。

scss

$size: 16px;
$color: #333;

.foo {
  font-size: $size;
  color: $color;
}
.bar {
  font-size: $size/2;
  color: #ccc;
}

css

.foo {
  font-size: 16px;
  color: #333;
}

.bar {
  font-size: 8px;
  color: #ccc;
}

$size, $color を変数で設定しました。

それぞれの値はそのまま呼び出すことができます。
また、SCSSではそのまま演算子を使うこともできます

配列変数

scss

$view: (sp: 10px, pc: 20px);

.foo {
  padding: map-get($view, sp);
}
.bar{
  margin: map-get($view, pc);
}

css

.foo {
  padding: 10px;
}

.bar {
  margin: 20px;
}

$view という変数に、 sp:10px, pc:20px という値を配列で入れました

map-get(XXX, YYY) で配列関数を呼び出します。
$view の 値が sp だったら 10px を返します。
$view の 値が pc だったら 20px を返します。

mixin

事前に設定したmixin(ミックスイン)を呼び出すことで、同じコードを別の位置に繰り返し記載することができます。

scss

@mixin tableBase {
  th {
    text-align: center;
    font-weight: bold;
  }
  td, th {
    padding: 2px
  }
}

.table {
  @include tableBase;
}

css

.table th {
  text-align: center;
  font-weight: bold;
}

.table td, .table th {
  padding: 2px;
}

tableBase という mixin でテーブルのスタイルを設定しました。
mixin で設定した値を .table で呼び出します。

コンパイル後は、.table の中にmixinで指定した記述が展開されます。

function

自作の関数を function として設定しておくと、任意の箇所から関数を呼び出すことができます。

scss

@function halfSize($value) {
  @return $value / 2;
}

.foo {
  width: halfSize(100px); 
}
.bar {
  height: halfSize(35px); 
}

css

.foo {
  width: 50px;
}

.bar {
  height: 17.5px;
}

halfSize という名前で、値を半分にする関数を設定しました。

SCSSでは値の箇所に 関数名を書き、引数で値を渡します
コンパイル後のCSSでは引数で渡した数値を半分にした値が挿入されます。

継承

scss

@import "hogehoge";

@import別のSCSSファイルを呼び出すことができます
この例では「hogehoge.scss」を呼び出しています。

例えば
変数だけを記載したSCSS、 mixinだけを記載したSCSS…
など機能ごとにファイルを分けておき、
それらを@importで呼び出すとファイルが見やすくなりますし、
複数のファイルで同じ設定を共有することも出来ます。

if文

scss

$position: right;

.foo {
  position: absolute;
  @if $position == 'right' {
    right: 0;
  } @else {
    left: 0;
  }
}

css

.foo {
  position: absolute;
  right: 0;
}

変数の値に合わせて返す値を変更する記述が出来ます。

例では、 $position が right という値だったら right: 0;
rightでない場合は left: 0; を返します。

for文

scss

@for $i from 1 through 3 {
  .order-#{$i} {
    order: $i;
  }
}

css

.order-1 {
  order: 1;
}

.order-2 {
  order: 2;
}

.order-3 {
  order: 3;
}

for を使うことで繰り返し処理を書くことが出来ます。

例では、1~3までで order を指定するCSSを記述しています。

変数などをセレクタ名で使用する場合は #{...} を使用し、
式展開してコンパイルさせます。
※式展開せずに記述すると「$i」など、そのままのテキストとしてCSSに展開されてしまいます。

each

scss

$colors: (
  red: #aa3333,
  blue: #3333aa,
  green: #33aa33
);

@each $color, $value in $colors {
  .block-#{$color} {
    background-color: $value;
  }
}

css

.block-red {
  background-color: #aa3333;
}

.block-blue {
  background-color: #3333aa;
}

.block-green {
  background-color: #33aa33;
}

配列変数などの場合は each をつかって展開することが出来ます。

$colors という変数配列を each で展開します。
このとき、 $color には red, blue などのテキストが格納され
$value には #aa3333, #3333aa などのカラーコードが格納されます。

while

scss

$padding: 10;

@while $padding <= 50 {
	.padding-#{$padding} {
		padding: $padding + px;
		$padding: $padding + 10;
	}
}

css

.padding-10 {
  padding: 10px;
}

.padding-20 {
  padding: 20px;
}

.padding-30 {
  padding: 30px;
}

.padding-40 {
  padding: 40px;
}

.padding-50 {
  padding: 50px;
}

while では、forと同じように繰り返し処理を記述することが出来ますが
例のように「ある値ごとに加算する」などの処理を行いたい場合に有効です。

例では $padding数値 10 を入れています。

$padding の数値が50以下の間で繰り返し処理を行います。

10pxごとにpaddingを指定するスタイルを用意したいので、
while で padding の指定後に 値を+10 します。

明度変更

scss

$color: red;

.foo {
  color: lighten($color, 30%);
}
.bar {
  color: darken($color, 30%);
}

css

.foo {
  color: #ff9999;
}

.bar {
  color: #660000;
}

$color に色を指定します。(16進記法でもrgb記法でも大丈夫)

lighten('変数', 'パーセント指定'); では指定した%の分だけ、変数の色を明るくします。
darken('変数', 'パーセント指定'); では指定した%の分だけ、変数の色を暗くします。

透明度変更

scss

$color: orange;

.foo {
  color: rgba($color, 0.5);
}

css

.foo {
  color: rgba(255, 165, 0, 0.5);
}

rgba('変数' '透過率'); で透過率を指定することも出来ます。

透過率は 0~1 の間で設定します。

もっと実用的なSCSS

ここまではSCSSの基本的な使い方を挙げて来ました。

ここからはBootstrapのSCSSから
ボタン要素のスタイルを参考に、実用的なSCSSの使い方を紹介します。

今回は .buttonprimary・.button-secondary・.button-tertiary という
3つのカラーのボタンを定義します。

ボタンのスタイルを作る

scss

//変数
$primary:       #0525a5;
$secondary:     #ebdf74;
$tertiary:      #8fa4f5;
$dark:          #333;
$light:         #fff;
$theme-colors:  (
  "primary":    $primary,
  "secondary":  $secondary,
  "tertiary":   $tertiary
);

// function
@function color-yiq($color) {
  $r: red($color);
  $g: green($color);
  $b: blue($color);
  $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
  @if ($yiq >= 100) {
    @return $dark;
  } @else {
    @return $light;
  }
}

//mixin
@mixin button-variant($color) {
  background-color: $color;
  color: color-yiq($color);
  &:hover, &:focus {
    background-color: lighten($color, 10%);
  }
  &:disabled, &.disabled {
    background-color: darken($color, 10%);
  }
}

//cssにコンパイルされる部分
.button {
  display: inline-block;
  width: 10rem;
  padding: .5rem 1rem;
  border-radius: 0.25rem;
  text-align: center;
  text-decoration: none;
}
@each $color, $value in $theme-colors {
  .button-#{$color} {
    @include button-variant($value);
  }
}

css

.button {
  display: inline-block;
  width: 10rem;
  padding: .5rem 1rem;
  border-radius: 0.25rem;
  text-align: center;
  text-decoration: none;
}

.button-primary {
  background-color: #0525a5;
  color: #fff;
}

.button-primary:hover, .button-primary:focus {
  background-color: #0730d7;
}

.button-primary:disabled {
  background-color: #041a74;
}

.button-secondary {
  background-color: #ebdf74;
  color: #333;
}

.button-secondary:hover, .button-secondary:focus {
  background-color: #f1e9a1;
}

.button-secondary:disabled {
  background-color: #e5d547;
}

.button-tertiary {
  background-color: #8fa4f5;
  color: #333;
}

.button-tertiary:hover, .button-tertiary:focus {
  background-color: #becaf9;
}

.button-tertiary:disabled {
  background-color: #607ef1;
}

解説:変数

scss

//変数
$primary:       #0525a5;
$secondary:     #ebdf74;
$tertiary:      #8fa4f5;
$dark:          #333;
$light:         #fff;
$theme-colors:  (
  "primary":    $primary,
  "secondary":  $secondary,
  "tertiary":   $tertiary
);

まずは変数から…

2~4行目:primary・secondary・tertiary それぞれのベースカラーを変数に入れます。
5~6行目:ボタンの色によって見やすい文字色を設定したいので 暗い文字色明るい文字色 をそれぞれ変数に指定しておきます。
7~11行目:2~4行目までの変数を $theme-colors(配列変数) で設定します。

解説:function

scss

// function
@function color-yiq($color) {
  $r: red($color);
  $g: green($color);
  $b: blue($color);
  $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
  @if ($yiq >= 100) {
    @return $dark;
  } @else {
    @return $light;
  }
}

function では color-yiq という関数を設定します。

この関数は 引数($color)の値にあわせて
暗い文字色・明るい文字色のどちらを利用するかを自動で決めます。

3~5行目:引数$color には先ほど設定した変数 primary・secondary・tertiary のいずれかの値が渡されます。
この値を red($color)・green($color)・blue($color)
16進記法から rの値・gの値・bの値 に分割します。

6行目:rgb色空間から yiq色空間に変更する計算を行い、その値を変数 $yiq に入れます。
※yiq色空間の計算式は変更しない

7~12行目:条件分岐を使い、 $yiq の値が
100以上の場合は暗い文字色
100よりも小さい場合は明るい文字色 を返すようにします。

解説:mixin

scss

//mixin
@mixin button-variant($color) {
  background-color: $color;
  color: color-yiq($color);
  &:hover, &:focus {
    background-color: lighten($color, 10%);
  }
  &:disabled, &.disabled {
    background-color: darken($color, 10%);
  }
}

mixinでは primary・secondary・tertiary という3つのカラーを使って
各色のボタンの色を設定します。

button-variant という名称で mixin を設定し、引数で色指定を渡します

3行目:背景色には primary・secondary・tertiary それぞれの値を入れます。
4行目:文字色の指定には先程の color-yiq関数 を呼び出します。
5~7行目:hoverとfocus 時には 背景色の明度を10%明るく 変更します
8~10行目:disabled 時には 背景色の明度を10%暗く 変更します

解説:ボタンスタイルを作る

scss

.button {
  display: inline-block;
  width: 10rem;
  padding: .5rem 1rem;
  border-radius: 0.25rem;
  text-align: center;
  text-decoration: none;
}
@each $color, $value in $theme-colors {
  .button-#{$color} {
    @include button-variant($value);
  }
}

ここからはCSSにコンパイルされる部分を記述していきます。

1~8行目:.button で適応される共通のスタイルを設定します。
これらは全ボタン共通のスタイルです。
9行目:配列変数の $theme-colorseach を使ってそれぞれの色でスタイルを生成します。

この時、$color には “primary” などのテキストが値として入っており、$value には “#0525a5” などのカラーコードが入っています。

10行目:classの指定には $color の値を利用します。

11行目:mixinを呼び出し(引数で $value を渡します)、背景色や文字色の設定を行います。

ブラウザでの表示例

実際のブラウザ表示例

実際にコンパイルしたCSSを当てたサンプルです。

まとめ

初めてSCSSを記述するときは「CSSで書いたほうが早いのでは?」と思うかもしれませんが、慣れてくるとCSSの記述よりも早く書ける・早く理解できるようになります。

また、BootstrapをはじめとするライブラリではSCSSを公開しているものあり、SCSSを使うことでカスタマイズすることもできます。

できることが広がるSCSS、興味のある方は是非導入してみてください。