Sass

Sassの機能を紹介

セレクタのネスト(入れ子)

セレクタを入れ子にすることができます。
例えばboxというクラスの子要素としてspan1、span2を定義した場合、普通のCSSだと下記のようになります。

.box {
	background-color: gray;
}
.box .span1 {
	color: red;
}
.box .span2 {
	color: blue;
}

これをSCSSだと下記のように書くことができるので、可読性とメンテナンス性を向上させることができます。

.box{
	background-color: gray;

	.span1{
		color: red;
	}
	.span2{
		color: blue;
	}
}

& セレクタ

& を使ってブロックの親セレクタを参照することができます。
例えば下記のa.btnクラスのHOVERを設定したい場合、セレクタを a.btn:hover とする代わりに &:hover と省略できます。

a.btn{
	border-radius: 5px;
	background-color: gray;
	&:hover{
	    color: red;
	}
}

出力結果は下記のようになります。

a.btn {
	border-radius: 5px;
	background-color: gray;
}
a.btn:hover {
	color: red;
}

次のように親セレクタ名をプレフィックスに使うこともできます。

#main {
	background-color: gray;
	&-sidebar {
		color: red;
	}
}

出力結果は下記のようになります。

#main {
	background-color: gray;
}
#main-sidebar {
	color: red;
}

@extend - セレクタを継承する

@extend は指定したセレクタのスタイルを継承することができます。
たとえばp1というクラスのスタイルを継承したい場合、下記のように記載できます。

.p1{
	background-color: gray;
}
.p2{
	@extend .p1; // .p1のスタイルを継承
	border: 1px solid black; // 追加のスタイルを記載できます
}

出力結果は下記のようになります。

.p1, .p2 {
	background-color: gray;
}

.p2 {
	border: 1px solid black;
}

継承元がネストしている場合、そのネストしている内容も継承されます。

.box1{
	color: black;
	.p1{
		background-color: gray;
	}
}
.box2{
	@extend .box1; // .p1のスタイルを継承
	border: 1px solid black; // 追加のスタイルを記載できます
}

出力結果は下記のようになります。

.box1, .box2 {
  color: black;
}
.box1 .p1, .box2 .p1, .box1 .p2, .box2 .p2 {
  background-color: gray;
}
.box2 {
	border: 1px solid black;
}

% プレースホルダーセレクタ

% プレースホルダ―セレクタを使って@extendすると、そのセレクタ自体は出力せず、スタイルのみ継承することができます。

%box {
	margin: 10px;
	padding: 10px;
}
.box1 {
	@extend %box;
	color: red;
}
.box2 {
	@extend %box;
	color: blue;
}

出力結果は下記のようになります。

.box1, .box2 {
  margin: 10px;
  padding: 10px;
}
.box1 {
  color: red;
}
.box2 {
  color: blue;
}

コメント

Sassには、通常のコメント /**/ 以外に、1行コメント用の // が用意されています。
//の1行コメントで記述すると、コンパイルされたCSSファイルにコメントが出力されません。

.box {
	// CSSにコメントは出力されません
	/* CSSにコメントが出力されます */
	background: gray;
}

出力結果は下記のようになります。

.box {
	/* CSSにコメントが出力されます */
	background: gray;
}

変数

Sassでは変数が使えます。
変数は下記のようにドル記号の後に変数名、値を指定します。

$変数名: 値;

例えば横幅の変数を作成し、利用する場合は下記のようになります。

$width: 5em;
#main {
	width: $width;
}

出力結果は下記のようになります。

#main {
	width: 5em;
}

値にはCSSで使える単位すべてを指定できます。

$width : 10px;
$width : 10%;
$width : 10;
$color : red;
$margin: 10px auto;

次のように四則計算も可能です。

$width:400px;
a{
	width: $width + 10px;
}

用意されている演算子には以下のようなものがあります。

+加算
-減算
*乗算
/除算
%余り

除算(/)はCSSでも使われているため、そのままだと四則計算として扱われないケースがあります。
変数や関数と一緒に使われていたり、括弧で囲まれていると演算子として使われるようになります。

p {
	$width: 1000px;

	font: 10px/8px;		// 変数無しでこの書き方だと計算されない
	font: (italic bold 10px/8px);	// 括弧で囲うと計算される
	width: $width/2;	// 変数と数値は計算される
	height: (500px/2);	// 括弧で囲うと計算される
	margin: round(1.5)/2;	// 関数が使われている場合は計算される
}

出力結果は下記のようになります。

p {
	font: 10px/8px;
	font: italic bold 1.25;
	width: 500px;
	height: 250px;
	margin: 1;
}

インターポレーション

変数は演算できない箇所では使えないため、例えば下記の場合、エラーになります。

$img_path:'/img';
.bg{
    background-image: url($img_path/bg.png);
}

そのような場合は変数を#{}で囲むことでエラーを回避することができます。

$img_path:'/img';
.bg{
    background-image: url(#{$img_path}/bg.png);
}

出力結果は下記のようになります。

.bg {
    background-image: url("/img/bg.png");
}

変数をクラス名として使いたい場合も有用です。

$v: class_name;
.#{$v} {
	color : blue;
}

CSSファイルのインポート

SCSSファイルはCSSと同様に外部ファイルをインポートすることができます。
CSSのインポートと違い、コンパイル時にインポート先の中身をインポート元に挿入して出力します。

@import "base.scss";
@import "foo.css";

CSSの@importはパラレルにファイルを読み込むことができないのでパフォーマンス的に問題がありますが、SCSSの@importは1つのファイルにまとめるので、パフォーマンス上の問題はありません。

パーシャル

Sassファイルをコンパイルしたくない場合、Sassファイルの頭に、_(アンダースコア)をつけると出力されなくなります。
下記ファイル名のSASSファイルはCSSにコンパイルされません。

_base.scss

コンパイルするSassファイルに、パーシャルなファイルをインポートする際は_(アンダースコア)を省略し下記のように記載できます。

@import "base.scss";

このように部分的に利用されることをパーシャルと言います。

配列

変数機能を使って配列を扱うこともできます。
配列を作成するには下記のように値をカンマ区切りで指定します。

$変数名: 値, 値, 値;

配列と後ほど説明する each を使って複数の背景画像URLを指定する方法を紹介します。

$array_img: img1, img2, img3; //配列
@each $f_name in $array_img {
	div.#{$f_name} {
		background-image: url(#{$f_name}.png);
	}
}

出力結果は下記のようになります。

div.img1 {
	background-image: url(img1.png);
}
div.img2 {
	background-image: url(img2.png);
}
div.img3 {
	background-image: url(img3.png);
}

Mixin

Mixinはスタイルのテンプレートを実現する機能です。
例えば下記のように@mixinを使ってスタイルを定義し、@includeでそのスタイルを呼び出すことができます。

@mixin round-btn{
	border-radius: 5px;
	background-color: gray;
}
.btn-blue{
	@include round-btn;	// round-btnのスタイルをインクルードします
	color: blue;
}

出力結果は下記のようになります。

.btn-blue {
	border-radius: 5px;
	background-color: gray;
	color: blue;
}

引数を使う

@include で呼び出すときに括弧内()に引数を指定することができます。
引数を複数指定する際はカンマ( , )で区切ります。 @include で呼び出す際に括弧内に値を指定すると、その値が引数として引き渡されます。

@mixin auto-color($color, $bg_color){
	color: $color;
	background-color: $bg_color;
}
.btn-red{
	@include auto-color(red,gray);
}

出力結果は下記のようになります。

.btn-red {
	color: red;
	background-color: gray;
}

デフォルトの値を設定する

引数のデフォルトの値を設定することもできます。
デフォルト値を指定しておくと、@include に引数を指定しなかった際にデフォルトの値が使われます。

@mixin auto-color($color:black, $bg_color:gray){
	color: $color;
	background-color: $bg_color;
}
.btn-red{
	@include auto-color(); // 引数無しで呼び出す
}

出力結果は下記のようになります。

.btn-red {
	color: black;
	background-color: gray;
}

@if - 条件分岐

@if を使って条件分岐を行うことができます。
@if文は、カッコの中の条件式を評価し、式が真のときだけ @if ブロックの命令文を実行します。

@if 条件1{
	処理
} @else if 条件2 {
	処理
} @else {
	処理
}

変数 $type の値によって処理を実行するには次のようにします。

$type : true;
a{ 
	@if $type == true {
		color: red; 
	} 
}

$typeの値が TRUE の時だけ color 属性に値が指定されます。
FALSE の際は何も出力されません。

複数の条件を並べたいときは、論理演算子の and もしくは or を使います。

$type1 : true;
$type2 : true
a{ 
	@if $type1 == true and $type2 == true {
		color: red; 
	} 
}

@if 文で複数の条件分岐を処理する

@if 文は複数の条件分岐にも使えます。@if の条件式が FALSEであった場合、さらにほかの条件式をためしたいときは、@else if 文を使います。どの条件式も FALSE だった場合は、@else 文を使って例外処理を行うことができます。@else はどの条件式も FALSE だったときのみ実行されます。

$type : a;
a{ 
	@if $type == a {
		color: red; 

	} @else if $type == b { 
		color: blue; 

	} @else { 
		color: white;
	} 
}

ここまでにでてきた == や != は比較演算子、and や or は論理演算子と呼びます。

比較演算子

比較演算子は左引数と右引数を比較し、その結果を論理値で返します。

演算子比較結果
==等しい左引数と右引数が等しければ真を返す。
!=等しくない左引数と右引数が等しくなければ真を返す。
>大きい左引数が右引数より大きければ真を返す。
<小さい左引数が右引数より小さければ真を返す。
>=以上左引数が右引数と同じか大きければ真を返す。
<=以下左引数が右引数と同じか小さければ真を返す。

論理演算子

論理演算しは「AとBが真ならば・・・」、「A、もしくはBのどちらかが真ならば・・・」など、式の真偽値を左から順に解釈していきます。

演算子論理結果
and論理積$a and $b$a と $b が真ならTRUEを返す
or論理和$a or $b$a もしくは $b が真ならTRUEを返す
not否定not $a$aが真でなければTRUEを返す

@for - 繰り返し構文

@for文は条件式の中で何回ループするかを明示的に指定してブロックを実行します。
@forの構文には種類が2つあり、指定した値まで繰り返す through と、指定した値未満まで繰り返す to が用意されています。

through:指定の値を繰り返す

@for 値を受け取る変数 from 開始値 through 終了値{
	処理
}

to:指定した値未満なら繰り返す

@for 値を受け取る変数 from 開始値 to 終了値{
	処理
}

throughを使った場合は下記のように記述します。

// 指定の値を繰り返す
@for $i from 1 through 3 {
	.item-#{$i} { width: 2em * $i; }
}

@for は開始値を繰り返すたびに +1 し、その値を「値を受け取る変数」に代入します。
そのため、$iには開始値の 1 から始まり、処理が繰り返されるたびに +1 された値が代入されます。through を使った @for の場合は、1から3までの値が代入されることになります。
出力結果は下記のようになります。

.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}
.item-3 {
  width: 6em;
}

toにした場合、条件などすべてthroughと同じでも、出力される回数が違います。

// 指定した値未満を繰り返す
@for $i from 1 to 3 {
	.item-#{$i} { width: 2em * $i; }
}

出力結果は下記のようになります。

.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}

@while - 繰り返し構文

@while 文は、条件式が真を返す限りブロック内を実行します。

@while 条件式{
	処理
}

@whileを使った例は下記のとおりです。

$i: 6;
@while $i > 0 {
	.item-#{$i} { width: 2em * $i; }
	$i: $i - 2;
}

$iには6が代入されていますが、@whileブロック内で-2しています。そのため処理が繰り返されるたびに $i の値は 6、4、2、0、-2・・・と減っていきますが、条件式で $i は0以上としていますので、$i の値が2の時まで繰り返されることになります。
よって、出力結果は下記のようになります。

.item-6 {
	width: 12em;
}
.item-4 {
	width: 8em;
}
.item-2 {
	width: 4em;
}

@each - 繰り返し構文

@each は配列の要素に対して繰り返しの処理を行います。

@each 値を受け取る変数 in リスト{
	処理
}

次の例では、@eachに渡す配列 $colors を作成し、その要素毎にクラスを作成しています。

// 配列を作成
$colors : red, green, blue;
@each $v in $colors {
	.#{$v}{
		color : $v;
	}
}

変数$vには red、 green、 blue が順番に代入され、その値をクラス名とCOLOR属性の値として使っています。
出力結果は下記のようになります。

.red {
  color: red;
}
.green {
  color: green;
}
.blue {
  color: black;
}

関連記事