SASS

SASS (scss) の基本的な使い方

Sass は Syntactically Awesome Style Sheets (構文的に素晴らしいスタイルシート) の略で、CSS を便利に使えるように拡張した言語です。

SASS Official Site

Sass には Sass 記法(拡張子 .sass)と SCSS 記法(拡張子 .scss)の二つの記法がありますが、ここでは SCSS 記法(拡張子 .scss)を使用します。現在はこちらが主流のようです。

SASS は CSS とは構文が異なるため CSS ファイルには SASS を記述することができません。SASS の場合は「.scss」という拡張子のファイルに記述します。

しかし、逆に通常の CSS を SASS ファイルに記述することは問題ありません。CSS ファイルの拡張子を「.css」から「.scss」に変更すると SASS ファイルになります。

SASS のインストールや設定に関しては検索するか「Sass/Compass のインストールと基本的な環境設定(2014年3月4日の記事なので少し古いですが)」をご参照ください。

現時点(2016年5月)での SASS の最新バージョンは、 Selective Steve (3.4.22) です。コマンドプロンプトで「sass -v」とタイプすると確認できます。

C:\Users\Foo>sass -v
Sass 3.4.22 (Selective Steve)

SASS オフィシャルサイトのドキュメント(マニュアル): SASS_REFERENCE(英語)

以下は SASS 関連のフォルダの例です。

Sass Folder Sample

SASS ファイルは SASS フォルダに保存し、コンパイルされた CSS は CSS に保存しています。「sass_batch.bat」は自動的に SASS ファイルをコンパイルするバッチファイルです。(これと同じ構成にする必要はありません)

コメント・文字コード

SASS では通常の CSS のコメント /* ..... */ も使えますが、JavaScript などで使用する // ..... のような1行コメントも使用できます。

.sample {
  //Comment ...
  width: 300px;
}

但し、CSS では1行コメントは使用できないのでコンパイルされると1行コメントは削除されます。通常の CSS のコメント /* ..... */ はコンパイルされても削除されずに残ります。

但し、アウトプットスタイル(コンパイルのフォーマット)を「compressed(圧縮)」にしていると CSS のコメントも削除されます。

「compressed」の場合でもコメントが消えないようにするには /*! */ で囲むようにします。

.sample {
  /*! Comment ... */
  width: 300px;
}

文字コードの指定

コメントなどに日本語を含める場合、ファイルの先頭で @charset を使用して UTF-8 を設定する必要があります。

文字コードを指定しないで、日本語を記述すると「Syntax error: Invalid Windows-31J character “\xE3″」のようなエラーになります。

また、「@charset “utf-8”;」と SCSS ファイルに指定しても、日本語のコメントなどを使用していない場合は、コンパイルされると「@charset “utf-8”;」の指定は CSS ファイルには書き出されません。

ネスト

SASS では、HTML 構造のように CSS をネストして(入れ子で)記述することができます。

以下のような HTML の場合を見てみます。

<div class="sample">
  <h3>Title</h3>
  <div class="content">
    <p>paragraph</p>
    <p>paragraph</p>
  </div>
</div>  

SASS では以下のように入れ子にしてスタイルを記述することが可能で、構造が把握しやすくなります。

//SASS (.scss)
.sample {
  border: 1px solid #999;
  background-color: #EEE;
  h3 {
    margin: 20px;
    font-size: 24px;
  }
  .content p {
    color: green;
  }
}

コンパイル後の CSS は以下のようになります。もしクラス名(sample)が変わった場合、SASS なら1箇所を修正するだけで済みます。

/* CSS コンパイル後*/
.sample {
  border: 1px solid #999;
  background-color: #EEE;
}
.sample h3 {
  margin: 20px;
  font-size: 24px;
}
.sample .content p {
  color: green;
}
プロパティのネスト

ショートハンドで記述できるプロパティ(ハイフンがあるプロパティ)でもネストを使うことが可能です。

//SASS (.scss)
.foo {
  border: {
    top: 1px solid #999;
    bottom: 2px dotted #666;
  }
}
/* CSS コンパイル後*/
.foo {
  border-top: 1px solid #999;
  border-bottom: 2px dotted #666;
}

また、下記のようにショートハンドで一度スタイルを指定してから、プロパティのネストで上書きすることも可能です。

//SASS (.scss)
.bar {
  margin: 10px {
    top: 0;
  }
}
/* CSS コンパイル後*/
.bar {
  margin: 10px;
  margin-top: 0;
}
@media のネスト

メディアクエリもネストして使うことができます。

//SASS (.scss)
.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
  }
}
/* CSS コンパイル後*/
.sidebar {
  width: 300px;
}
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}

親セレクタの参照 (&)

セレクタに「&」を使うとネストしている親セレクタを参照することができます。

//SASS (.scss)
a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
}
/* CSS コンパイル後*/
a {
  font-weight: bold;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
body.firefox a {
  font-weight: normal;
}

以下のようにネストが深くなっても、親セレクタを参照できます。

//SASS (.scss)
#main {
  color: black;
  a {
    font-weight: bold;
    &:hover { color: red; }
  }
}
/* CSS コンパイル後*/
#main {
  color: black;
}
#main a {
  font-weight: bold;
}
#main a:hover {
  color: red;
}

以下のような使い方もできます。

//SASS (.scss)
#main {
  color: black;
  &-sidebar { border: 1px solid; }
}
/* CSS コンパイル後*/
#main {
  color: black;
}
#main-sidebar {
  border: 1px solid;
}

変数(Variables: $)

変数(variable)とは、データ(値)を一時的に記憶しておくための仕組みで、任意の名前を付けておき、必要に応じてデータ(値)を呼び出すことができます。

SASS の変数では以下のような決まりがあります。

  • 変数の宣言は、名前は「$」から始め、「:」で区切って値を指定します
  • 変数名は英数字の他にアンダースコア「_」とハイフン「-」の記号を使うことができます()(他の記号は使えません)
  • また、マルチバイト文字も使えるので使おうと思えば日本語も使用可能ですが、「@charset “utf-8”;」を冒頭で宣言する必要があります
  • 半角数字から始まる名前や連続したハイフンから始まる名前はエラーになります
  • 基本のフォントカラーやリンクカラー、ベースフォントなどを予め指定しておくと便利です

以下は基本的な使い方です。

//SASS (.scss)
$width: 5em;  //変数の宣言

#main {
  width: $width;  //変数の使用
}
/* CSS コンパイル後*/
#main {
  width: 5em;
}

以下はもう少し実用的な使い方の例です。

//SASS (.scss)
/*コメントや content に日本語を含める場合、
ファイル先頭で @charset で UTF-8 を指定します*/
@charset "utf-8";  
 
$main_width: 960px;
 
// ベースフォント  
$base_font: "メイリオ", "Meiryo", verdana, "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", Osaka, "MS Pゴシック", "MS PGothic", Sans-Serif;  
   
// ベーステキストカラー  
$base_font_color: #333;  
   
// ベースリンクカラー  
$base_link_color: #06f;  
$base_link_color_hover: #00f;  
 
body {  
    color: $base_font_color;  
    font-family: $base_font;  
}  
#main {
    width: $main_width;  
    a:link {  
        color: $base_link_color;  
    }  
    a:hover {  
        color: $base_link_color_hover;  
    }  
}
/* CSS コンパイル後*/
@charset "UTF-8";
body {
  color: #333;
  font-family: "メイリオ", "Meiryo", verdana, "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", Osaka, "MS Pゴシック", "MS PGothic", Sans-Serif;
}

#main {
  width: 960px;
}
#main a:link {
  color: #06f;
}
#main a:hover {
  color: #00f;
}

アンダースコアとハイフン

Sass の変数名(やその他の識別子)では、アンダースコア「_」とハイフン「-」は互換性があります。例えば $main-width という変数を定義するとその変数を $main_width で参照することができてしまいます。どちらかに統一した方が管理しやすいかも知れません。

For historical reasons, variable names (and all other Sass identifiers) can use hyphens and underscores interchangeably. For example, if you define a variable called $main-width, you can access it as $main_width, and vice versa.
//SASS (.scss)
$main_width: 30px;

.foo {
	width: $main-width;
}
/* CSS コンパイル後*/
.foo {
  width: 30px;
}
別の Sass ファイルで宣言した変数

別の Sass ファイルで宣言した変数でも、@import ルールを使ってインポートしていればその変数を参照することが可能です。但し、参照する変数を宣言した Sass ファイルが先に読み込まれている必要があります。

Sass のインポートについては後述の「Sass の @import」を参照ください。

変数を使用(参照)できる場所

基本的に変数はプロパティの値として使用(参照)しますが、セレクタ名や画像のパスの一部として使用したい場合は、インターポレーション(補完)を使います。

変数の有効範囲(スコープ)
  • 変数には有効範囲(スコープ)があり、トップレベルの位置(ドキュメントルート)で書いた変数はどこでも有効ですが、波括弧の中(ルールセット内)で変数を定義すると、その括弧の中のみが有効範囲になります。(例外として、 !global フラグの使用があります)
  • 波括弧の中(ルールセット内)の変数は波括弧の外からはアクセスできませんが、ネストでどれだけ入れ子が深くなっても利用することができます。
  • トップレベルで定義されたものをグローバル変数、波括弧の中で定義されたものをローカル変数と呼ぶこともあります。
//SASS (.scss)
$padding: 10px;  //ドキュメントルート

.foo {
  $value : 30px; //ルールセット内
  margin: $value;  //参照可能 
  p {
    padding: $padding; //参照可能 
    margin: $value;  //参照可能  
  }
}

.bar {
  margin:  $value;  //参照不可(エラー)
}

!global フラグ

波括弧の中(ルールセット内)で変数を定義すると、その括弧の中のみが有効範囲になりますが、「!global」フラグを付けると、その変数はどこからでも有効になり参照可能になります。

//SASS (.scss)
#main {
  $width: 5em !global;
  width: $width;
}

#sidebar {
  width: $width;  //参照可能 (エラーにならない)
}
/* CSS コンパイル後*/
#main {
  width: 5em;
}

#sidebar {
  width: 5em;
}
!defaut フラグ(デフォルト値の設定)

!default フラグは、変数にまだ値が設定されていない場合にのみ値を設定するフラグです。

通常変数の値は、後から宣言された変数の値で上書きされますが、!defaut フラグを使用すると、同じ変数が先に宣言されていた場合そちらが優先されます。

もし変数に既に値が設定されている場合はその値が使用され、まだ値が設定されていない場合は !default フラグで指定された値が設定されます。

//SASS (.scss)
.foo {
  $theme-color: green; //ローカル変数
  color: $theme-color; // green
}

$theme-color: red; //グローバル変数

.bar {
  $theme-color: green !default; //!defaultフラグを指定
  color: $theme-color; //!defaultの前にグローバル変数が定義されているのでred
}
/* CSS コンパイル後*/
.foo {
  color: green;
}

.bar {
  color: red;
}

!default フラグは、実際には Sass のパーシャルファイルを使う場合などで利用します。

Sass ファイルを以下のように分割しているとします。

  • base.scss(import とメインのスタイル)
  • _extend.scss(@extend 用)
  • _setting.scss(設定関連)
//_extend.scss
%roundCorner {
  $borderRadius: 6px !default; // !defaultフラグを指定
  border-radius: $borderRadius;
}
//_setting.scss
$borderRadius: 4px;
//base.scss
@import "setting";
@import "extend";

.foo {
  @extend %roundCorner;
}
/* CSS コンパイル後*/
.foo {
  border-radius: 4px;
}

このように @extend などで予め値を指定しつつ変更可能にしておく場合のように、上書きされる前提で !default フラグは使います。

Sass のデータタイプ(型)

Sass には型(データタイプ)が存在し、現在7種類に分類されています。

  • Number:数値(単位を含む)
  • String:文字列
  • Color:色(カラーコード)
  • Boolean:真偽値
  • Null:空の値
  • List:リスト(配列)
  • Map:マップ(連想配列)
Number 型(数値)
整数、単位、浮動小数点など、数が値になるもの(px や em などの単位も含まれます
String 型(文字列)
数値や色、true、false などに該当しない文字やダブルクォーテーションやシングルクォーテーションに囲まれたもの
Color 型(色)
キーワード(カラーネーム)、HEX(#FEFEFE等)、rgb()、rgba()、hsl() などの全ての色の値
Boolean 型(真偽値)
true と false の2種類
Null 型(空の値)
空の値は Null 型となります。Sass は値が Null 型の場合、プロパティを書き出さないようになっています。
List 型(リスト/配列)
リストは値をカンマやスペース、カッコで区切ったものです。入れ子にすることで多次元配列も作成可能です。
以下は区切り文字が異なるだけで同じ内容のリストです。
$names : foo, bar, baz;
$names : foo bar baz;
Map 型(マップ/連想配列)
マップは任意の名前(キー)と値のペアが集まったものです。
$map: (key1: value1, key2: value2, key3: value3);

データタイプの確認

データタイプは type-of 関数で確認することができます。

//SASS (.scss)
type-of(100px)  => number
type-of(asdf)   => string
type-of("asdf") => string
type-of(true)   => bool
type-of(#fff)   => color
type-of(blue)   => color
type-of(null)   => null
$list: foo, bar, baz;
type-of($list)   => list
$map: (foo:100, bar:200, baz:300);
type-of($map)   => map

演算(Operations)

Sass では、四則演算や文字列の連結、色の演算等を行うことが可能です。

数値の操作(四則演算)

Sass では数値型の値に計算の記号を使うことで計算をすることができます。単位を省略すると元の単位にあわせて計算されます。

//SASS (.scss)
.thumb {
  width: 200px - (5 * 2) - 2;
  padding: 5px + 3px;
  border: 1px * 2 solid #ccc;
}
/* CSS コンパイル後*/
.thumb {
  width: 188px;
  padding: 8px;
  border: 2px solid #ccc;
}

計算で使える記号には、以下のようなものがあります。

  • +(プラス):足し算
  • -(ハイフン):引き算
  • *(アスタリスク):掛け算
  • /(スラッシュ):割り算
  • %(パーセント):割った余りを求める(剰余)

実際には、以下のように変数を使って計算することが多いと思います。

//SASS (.scss)
$main_width: 600px;
$border_width: 2px;

.foo {
  $padding: 5px;
  width: $main_width - $padding * 2 - $border_width *2;
}
/* CSS コンパイル後*/
.foo {
  width: 586px;
}

割り算とスラッシュ

CSS では半角のスラッシュを値を分離する方法として使うことができます。このためスラッシュを使用した時、割り算になるのは、以下のいずれかに当てはまる場合になります。

  • 値が変数に格納されている
  • 丸括弧の中で使われている
  • 値が別の計算の一部になっている
//SASS (.scss)
p {
  $width: 100px;
  width: $width/2;    // 変数に対しての割り算
  height: (700px/2);    //丸括弧の中の割り算
  margin-left: 5px + 8px/2px; //割り算と足し算
}
/* CSS コンパイル後*/
p {
  width: 50px;
  height: 350px;
  margin-left: 9px;
}

引き算(-)の注意点

マイナス(-)はハイフンと同じ記号なので、引き算や負の値の記号、文字としてのハイフンなどの意味があります。そのため、確実に引き算にするには、マイナス(-)記号の前後に半角のスペースを入れるようにします。

その他の記号の前後にも半角スペースを入れるようにすると、記述方法が統一されるので良いでしょう。

文字列の連結

プラス(+)は文字列を連結する演算子としても使うことができます。

//SASS (.scss)
p {
  cursor: e + -resize;
}
/* CSS コンパイル後*/
p {
  cursor: e-resize;
}

引用符が付いている文字列と付いていない文字列を連結する場合は、最初の文字列の形式(引用符ある・ない)に変換されます。

//SASS (.scss)
p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}
/* CSS コンパイル後*/
p:before {
  content: "Foo Bar";
  font-family: sans-serif;
}
色の演算

Sass では色の演算も可能です。あまり感覚的ではないので、色の関数を使用するほうが簡単かも知れません。

//SASS (.scss)
p {
  color: #010203 + #040506;
}

01 + 04 = 05, 02 + 05 = 07, 03 + 06 = 09

/* CSS コンパイル後*/
p {
  color: #050709;
}

RGB 16進数の他に、rgb(), hsl() などでも計算が可能です。但し、アルファチャンネル(色の透明度)を含む rgba(), hsla() を使用する場合は、同じ値の透明度を指定する必要があるようです。

//SASS (.scss)
a.foo:hover {
  color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}
/* CSS コンパイル後*/
a.foo:hover {
  color: rgba(255, 255, 0, 0.75);
}

Sass の @import

Sass では通常の CSS の @import も使うことができます。また、@import の書き方は Sass と CSS で同じですが、条件によって Sass の @import か CSS の @import かが決まります。

通常の CSS の @import

CSS の @import は外部の CSS ファイルを読み込むのに使い、以下のいずれかの方法で記述します。

@import url("test.css");
@import url(test.css);
@import "test.css";
@import 'test.css';
 
/* メディアタイプの指定をする場合 */
@import "test.css" screen;
  • @import では必ず最後のセミコロン(;)を記述する必要があります。
  • パスの指定は、インポート元の CSS ファイルが基準となります(同じディレクトリ内にあれば、ファイル名だけでよい)。
  • CSS ファイル内のルールセットより先(@charset があればその直後)に記述する必要があります。

また、CSS ファイル内で Sass ファイルをインポートしても、ブラウザでは認識されないので意味がありません。

Sass の @import

  • Sassの @import は、ファイル内のどこにでも記述することができます。
  • Sass の場合、インポートした Sass ファイルの中に展開され、1つの CSS ファイルとして生成されます。但し、この時インポートした Sass ファイルも CSS ファイルとしてコンパイルされてしまい、不要な CSS ファイルが生成されてしまいます(後述の partial を使うことで回避できます)。

また以下のような場合、Sass ファイルとしてではなく CSS ファイルとしてインポートされます。

  • ファイル名に拡張子 .css がついている: @import “foo.css”;
  • ファイル名が http:// から始まっている: @import “http://foo.com/bar”;
  • url()が使用されている: @import url(foo);
  • メディアタイプを指定している: @import “foo” screen;

上記のいずれにも当てはまらない場合、Sass コンパイラは .scss か .sass のファイル名であるとみなして、Sass プロジェクト内の指定されたファイルをインポートします。また、load-path オプションが指定されていれば、オプションで指定されたディレクトリを探します。

ファイルの分割(partial)

Sass は分割した Sass ファイルを一つの CSS ファイルとしてまとめることが可能です。

インポートした Sass ファイルはコンパイルすると CSS ファイルとして生成されますが、CSS ファイルとして生成したくない場合は、ファイル名の先頭にアンダースコア「_」を付けることで、コンパイルしても CSS ファイルを生成しないようにすることができます。

  • Sass ファイル名の先頭にアンダースコアを付けると、コンパイルしても CSS ファイルが生成されないという仕様があり、この部分的な Sass ファイルまたは機能をパーシャル(partial)と呼びます。
  • これにより「Sassではファイルを分割して管理するが、コンパイル後に生成される CSS ファイルは1つだけ」ということが可能になります。
  • partial は、CSSファイルには変換されないため、最終的に CSS ファイルとして変換したいメインの Sass ファイルから読み込むようにします。

パーシャル(partial)のインポート

パーシャルを読み込む(インポートする)場合は、拡張子とアンダーバーを省略することができます(拡張子やアンダーバーをつけたままでも問題ありません)。

ファイル名が「_foo.scss」「_bar.scss」「_baz.scss」の場合、以下のように記述することができます。

//SASS (.scss)
@import 'foo';
@import 'bar.scss';
@import '_baz';
 
//カンマで区切ってまとめて読み込むことも可能
@import "foo", "bar", "baz";
 
//階層が違う場合はディレクトリ名を指定  
@import "contents/foo";  
@import "contents/_bar";

Sass の @import は、ファイル内のどこに記述しても良いので、印刷用のスタイルだけ最後に読み込む場合は次のように記述することができます。

//SASS (.scss)
@import "reset";   
// メインのスタイル
body { 
   ・・・
}  
・・・    
// 印刷用スタイル の読み込み 
@import "print";

@import のネスト

Sass の @import ではルールセット内および @media ルール内で使用することができます。以下はルールセット内で @import を使用する例です。

//_foo.scss
a {
  color: #333;
}

p {
  margin:1em;
}
//bar.scss
#main {
  @import "_foo";
}
/* CSS コンパイル後 bar.css*/
#main a {
  color: #333; 
}
#main p {
  margin: 1em; 
}
パーシャルを使ったディレクトリ/ファイル構成

以下はパーシャルを利用した Sass のディレクトリ/ファイル構成の一例です。

project
  |_css/
  |   |- style.css(生成される CSS)
  |   
  |_sass/
      |- _reset.scss(リセット用)
      |- _extend.scss(@extend の定義)
      |- _mixin.scss(@mixin の定義)
      |- _settings.scss(変数などの設定の定義)
      |- style.scss(メインのスタイルと各Sassファイルのインポート用)

それぞれの用途に Sass ファイルをパーシャルファイルとして分割して、style.scss で各 Sass ファイルをインポートするようにすると、1つの CSS ファイル(style.css)が生成されます。

セレクタの継承 @extend

@extend は指定したセレクタのスタイル(定義したスタイル)を継承する機能です。

ルールセットの中で他のセレクタで指定してあるルールを利用(転用)することができます。

以下は、.basicBox で定義したスタイルを .foo で継承する例です。スタイルを継承するには、@extend の後に継承するセレクタ名を記述します。

//SASS (.scss)
.basicBox {
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
}

.foo {
  @extend .basicBox;
}

コンパイル後の CSS を見ると、2つのセレクタがグループ化されているのがわかります。このように @extend を使うと、セレクタがグループ化され、うまく利用すると記述量を減らすことができます。

/* CSS コンパイル後*/
.basicBox, .foo {
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
}

以下は、.basicBox で定義したスタイルを .foo と .bar で継承する例です。.foo では独自に背景色と角丸ボーダーの指定を追加し、.bar では .basicBox で定義したスタイルを上書きしています。

//SASS (.scss)
.basicBox {
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
}

.foo {
  @extend .basicBox;
  background-color: #EEE;
  border-radius: 5px;
}

.bar {
  @extend .basicBox;
  padding: 20px;
  border: 2px dashed #AAA;
}
/* CSS コンパイル後*/
.basicBox, .foo, .bar {
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
}

.foo {
  background-color: #EEE;
  border-radius: 5px;
}

.bar {
  padding: 20px;
  border: 2px dashed #AAA;
}

このように @extend はベースとなるスタイルのクラスとして作成しておいて、それぞれのクラスで必要に応じてカスタマイズする場合などに便利かと思います。

また、@extend はルールセット内で複数指定することも可能です。

@extend 用のプレースホルダーセレクタ %

@extend はセレクタを継承するので、コンパイル後の CSS には継承元のセレクタも生成されます。

@extend 専用としてセレクタを書きたい場合などで、継承元のセレクタは不要な場合は ID(#)やクラス(.)セレクタの代わりに、「%」をセレクタとして使うことでそのセレクタを生成させないことができます。

以下は前述の例と同じ内容ですが、継承元のセレクタを「.」から「%」に変更しています。

//SASS (.scss)
%basicBox {
  margin: 20px;
  padding: 10px;
  border: 1px solid #999;
}

.foo {
  @extend %basicBox;
  background-color: #EEE;
  border-radius: 5px;
}

.bar {
  @extend %basicBox;
  padding: 20px;
  border: 2px dashed #AAA;
}

%basicBox のセレクタが生成されていないことがわかります。

/* CSS コンパイル後*/
.foo, .bar {
  margin: 20px;
  padding: 10px;
  border: 1px solid #999;
}

.foo {
  background-color: #EEE;
  border-radius: 5px;
}

.bar {
  padding: 20px;
  border: 2px dashed #AAA;
}

以下は @extend 用のパーシャルファイル(_extend.scss) を用意して、style.scss にインポートして使用する例です。

このようにファイルを分けておくと管理が楽になります。

//SASS (_extend.scss)
%basicBox {
  margin: 20px;
  padding: 10px;
  border: 1px solid #999;
}
//SASS (style.scss)
@import "extend";  //_extend.scss をインポート

.foo {
  @extend %basicBox;
  background-color: #EEE;
  border-radius: 5px;
}
.bar {
  @extend %basicBox;
  padding: 20px;
  border: 2px dashed #AAA;
}
/* CSS コンパイル後 (style.css)*/
.foo, .bar {
  margin: 20px;
  padding: 10px;
  border: 1px solid #999;
}
.foo {
  background-color: #EEE;
  border-radius: 5px;
}
.bar {
  padding: 20px;
  border: 2px dashed #AAA;
}
@media 内での @extend

@media 内では @extend は使用できません。以下のように記述すると「Sass::SyntaxError: You may not @extend an outer selector from within @media.」のようなエラーとなり、コンパイルされません。

//SASS (.scss)
%foo {
  border: 1px solid #999;
  padding: 10px;
  background: #EEE;
}

@media screen and (min-width:960px){
  .bar {
    @extend %foo;  //エラーとなる
  }
}

@media 内で使用するには、@media 内に継承したいセレクタを記述します。

//SASS (.scss)
@media screen and (min-width:960px){
  %foo {
    border: 1px solid #999;
    padding: 10px;
    background: #EEE;
  }
  .bar {
    @extend %foo;
  }
}
/* CSS コンパイル後*/
@media screen and (min-width: 960px) {
  .bar {
    border: 1px solid #999;
    padding: 10px;
    background: #EEE;
  }
}
@extend が使える/使えないセレクタ

@extend は、子孫セレクタや子セレクタなど複数のパターンが成立するセレクタには使うことができません。

@extend が使えるセレクタ

  • クラスセレクタ .foo など
  • タイプセレクタ div, p, a など
  • ID セレクタ #bar など
  • 連結セレクタ .foo.bar など
  • 属性セレクタ input[type=”radio”] など
  • 疑似クラス :hover, :link など
  • 疑似要素 :before, :after など

@extend が使えないセレクタ

  • 子孫セレクタ .item p など
  • 子セレクタ #main > article など
  • 隣接セレクタ h2 + h3 など
  • 間接セレクタ h3 ~ h3 など

ミックスイン @mixin

CSS では、一度定義した CSS の再利用は難しいですが、Sass ではミックスインを使うことで CSS の再利用が可能になります。

  • ミックスインを使うとプロパティやセレクタをまとめてワンセットにしておいて、それらを読み込むことができます。
  • ミックスインは @mixin ディレクティブを用いて定義し、@include ディレクティブで定義したミックスインを呼び出します。
  • ミックスインは、@include で挿入した箇所で展開されるコード片で、ミックスイン自体のコードは CSS としてコンパイルされず、@include されてはじめて実体を持ちます。
  • そのため、よく使うものを一通りライブラリとして読み込んでおいて必要に応じて呼び出す、という使い方が可能です。
  • ミックスインもスコープを持つので、ルールセット内で定義するとその中でしか利用できません。
  • またミックスインでは引数を取ることができるので、より使い回しが柔軟にできます。

ミックスインは、@mixin の後に半角スペースを置き、任意の名前で定義します。

//SASS (.scss)
@mixin ミックスイン名 {  
  // ミックスインの定義
}

.foo {
  @include ミックスイン名;  
}
//SASS (.scss)
@mixin grayBox {  // ミックスインの定義
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
  background-color: #EEE;
  color: #333;
}

.foo {
  @include grayBox;  // 定義したミックスインの呼び出し
}
/* CSS コンパイル後*/
.foo {
  margin: 20px 0;
  padding: 10px;
  border: 1px solid #999;
  background-color: #EEE;
  color: #333;
}
引数を使ったミックスイン

ミックスインは引数を取ることができます。引数はミックスイン名の後に括弧を書き、その括弧の中に記述します。引数が複数ある場合は、カンマで区切って記述します。また、引数は一種の変数なので、変数と同様に名前は「$」から始めます。

//SASS (.scss)
@mixin my-border($color, $width, $radius) {
  border: {
    color: $color;
    width: $width;
    radius: $radius;
  }
}

p {
  @include my-border(blue, 1px, 3px);
}
/* CSS コンパイル後*/
p {
  border-color: blue;
  border-width: 1px;
  border-radius: 3px;
}
引数に初期値を設定

引数の初期値を設定しておくと、初期値と同じ値を使用する場合は、引数を省略することができます。よく使う値があれば、初期値を設定しておくと便利です。

引数の初期値を設定するには、変数と同じ書式(名前は「$」から始め、「:」で区切って値を指定)で記述します。

呼び出す際は、引数が初期値と同じ場合は、()や値は省略することができます。初期値と値が異なる場合だけ、引数の値を指定します。

//SASS (.scss)
@mixin kadomaru($radius: 5px) {
  border-radius: $radius;
}

.foo {
  @include kadomaru;
}
.bar {
  @include kadomaru();
}
.baz {
  @include kadomaru(10px);
}
/* CSS コンパイル後*/
.foo {
  border-radius: 5px;
}
.bar {
  border-radius: 5px;
}
.baz {
  border-radius: 10px;
}

初期値を設定した引数を複数指定

以下のように2つの初期値を設定した引数がある場合、2つ目の値が初期値と同じ場合は、省略することができます。

但し、1つ目の値が初期値と同じで、2つ目が異なる場合は、1つ目を省略することができません。以下のように1つ目の値を同じ値に指定する必要があります。

//SASS (.scss)
@mixin kadomaruBox($radius: 5px, $bgColor: #EEE) {
  border-radius: $radius;
  background-color: $bgColor;
}

.foo {
  @include kadomaruBox(4px);
}
.bar {
  @include kadomaruBox(5px, #EFEFEF);
}

//以下のように一つ目を省略するとエラーになります。
.baz {
  @include kadomaruBox(, #EFEFEF);  //エラー
}

または、引数名をつけて値を指定すると、順序を気にしないで引数を渡すことができます。

//SASS (.scss)
@mixin kadomaruBox($radius: 5px, $bgColor: #EEE) {
  border-radius: $radius;
  background-color: $bgColor;
}

.foo {
  @include kadomaruBox(4px);
}
.bar {
  @include kadomaruBox(5px, #EFEFEF);
}

.baz {
  @include kadomaruBox($bgColor:#EFEFEF);  //エラーにならない
}

「引数名:値」の形式で引数を指定すれば、順序を気にしないで必要な引数のみを渡すことができます。

/* CSS コンパイル後*/
.foo {
  border-radius: 4px;
  background-color: #EEE;
}

.bar {
  border-radius: 5px;
  background-color: #EFEFEF;
}

.baz {
  border-radius: 5px;
  background-color: #EFEFEF;
}

以下はリンクカラーのミックスインの例です。第3引数の $active には初期値として null を設定しているので、第3引数を指定しなければ、:active は出力されません。

//SASS (.scss)
@mixin link-color($normal, $hover, $active: null){
  color: $normal;
  &:hover {
    color: $hover;
    text-decoration: none;
  }
  @if $active {
    &:active {
      color: $active;
      text-decoration: none;
    }
  }
}

.foo a {
  @include link-color(#2B69C7, #365DA0);
}
/* CSS コンパイル後*/
.foo a {
  color: #2B69C7;
}
.foo a:hover {
  color: #365DA0;
  text-decoration: none;
}
カンマ(,)を使うプロパティ

基本的にミックスインには引数1つに対して1つの値しか渡すことができません。

但し、box-shadow, text-shadow などのプロパティのようにカンマ区切りで複数の値を指定できるものがあります。

以下の例では、複数の影を指定した .bar はエラーになってしまいます(1つの引数に対して、2つの引数を指定したことになってしまいます)。

//SASS (.scss)
@mixin boxShadow($values) {
  box-shadow: $values;
}

.foo {
  @include boxShadow(3px 3px 8px #999);
}

//エラーになる
.bar {
  @include boxShadow(3px 3px 8px #999, -3px -3px 8px #CCC);
}

リストを使う

回避策の1つはリストを使う方法です。複数の値を () で囲ってリスト(配列)にして1つの値として渡します。

//SASS (.scss)
@mixin boxShadow($values) {
  box-shadow: $values;
}

.foo {
  @include boxShadow(3px 3px 8px #999);
}

//エラーにならない
.bar {
  @include boxShadow((3px 3px 8px #999, -3px -3px 8px #CCC));
}

可変長引数(Variable Arguments)を使う

もう一つの回避策は、可変長引数を使う方法です。可変長引数を使うには、引数の後に「...」(3つのドット)を記述します。

//SASS (.scss)
@mixin boxShadow($values...) {  //引数の後に ... を記述
  box-shadow: $values;
}

.foo {
  @include boxShadow(3px 3px 8px #999);
}

//エラーにならない
.bar {
  @include boxShadow(3px 3px 8px #999, -3px -3px 8px #CCC);
}

ミックスインの呼び出しに可変長引数を使う

ミックスインを呼び出す(@include する)際にも可変長引数を使うことができます。

例えば以下のように変数に値を格納して、ミックスインを呼び出すとエラーになってしまいます。

//SASS (.scss)
@mixin colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;

//エラーになる
.foo {
  @include colors($values);
}

この場合、以下のように可変長引数にすることでエラーになりません。

//SASS (.scss)
@mixin colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;

.foo {
  @include colors($values...);  //エラーにならない
}
/* CSS コンパイル後*/
.foo {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}
ミックスインのスコープ

ミックスインにも有効範囲(スコープ)があります。そのため、ルールセット内でミックスインを定義すると、そのルールセット内でしか利用できなくなります。

以下の例ではクラス foo の中でミックスインを定義しているので、クラス bar の中で使おうとするとエラーになります。

//SASS (.scss)
.foo {
  @mixin kadomaru {
    border-radius: 6px;
  }
  .rc {
    @include kadomaru;
  }
}

//エラーになる
.bar {
  @include kadomaru;
}
ミックスインにコンテンツを渡す @content

@content はルールセットやスタイルなどのコンテンツ(内容)をミックスインに渡す機能です。

ミックスインを定義する際、渡されたコンテンツ(内容)を入れたい場所に @content を記述します。そして @include する際に波括弧 { } で括ってコンテンツ(内容)を記述すると、ミックスインで @content を記述した場所にそのコンテンツ(内容)が展開されます。

//SASS (.scss)
@mixin basicBox {
  width: 300px;
  border: 1px solid #999;
  background: #EEE;
  @content;  //ここにコンテンツが展開される
}
     
.alert {
  @include basicBox {
    color: #F00; //コンテンツ
    font-weight: bold; //コンテンツ
  }
}

.normal {
  @include basicBox {
    color: #666; //コンテンツ
  }
}
/* CSS コンパイル後*/
.alert {
  width: 300px;
  border: 1px solid #999;
  background: #EEE;
  color: #F00; //展開されたコンテンツ
  font-weight: bold; //展開されたコンテンツ
}

.normal {
  width: 300px;
  border: 1px solid #999;
  background: #EEE;
  color: #666; //展開されたコンテンツ
}

以下は、メディアクエリを使った例です。

@content の部分に、@include する際に波括弧 { } で括ったコンテンツ(内容)が展開されます。

//SASS (.scss)
@mixin foo($max-width: 960px){
  @media only screen and (max-width: $max-width) {
    @content;  //ここにコンテンツが展開される
  }
}

@include foo(600px) {
  body {  //コンテンツ(ここから)
    color: #666;
    font-size: 14px; 
  } //コンテンツ(ここまで)
}
/* CSS コンパイル後*/
@media only screen and (max-width: 600px) {
  body {
    color: #666;
    font-size: 14px;
  }
}

以下も、メディアクエリを使った例です。

$breakpoint_small, $breakpoint_medium, $breakpoint_large はブレークポイント(min-width)を指定する変数です(必要に応じて変更したり、増やしたりします)。

//SASS (.scss)
$breakpoint_small: 480px;
$breakpoint_medium: 600px;
$breakpoint_large: 960px;

@mixin media($size) {
  @if $size == s {
    @media only screen and (min-width : $breakpoint_small){
      @content;
    }
  }
  @else if $size == m {
    @media only screen and (min-width : $breakpoint_medium){
      @content;
    }
  }
  @else if $size == l {
    @media only screen and (min-width : $breakpoint_large){
      @content;
    }
  }
}

#content {
  /* 小さいサイズ及び共通の設定等を記述 */

  @include media(s) {
    width: 96%;
  }
  @include media(m) {
    width: 94%;
  }
  @include media(l) {
    width: 960px;
  }

}
/* CSS コンパイル後*/
#content {
  /* 小さいサイズ及び共通の設定等を記述 */
}
@media only screen and (min-width: 480px) {
  #content {
    width: 96%;
  }
}
@media only screen and (min-width: 600px) {
  #content {
    width: 94%;
  }
}
@media only screen and (min-width: 960px) {
  #content {
    width: 960px;
  }
}

キーフレームを出力するミックスイン

以下は、キーフレームを出力するミックスインの例です。プレフィックスが必要な場合は、それぞれの引数の値を「true」に指定します。

//SASS (.scss)
@mixin keyframes($name, $webkit:true, $moz: false, $ms: false, $o: false ){
  @if $webkit {
      @-webkit-keyframes #{$name} {
      @content;
    }
  }
  @if $moz {
      @-moz-keyframes #{$name} {
      @content;
    }
  }
  @if $ms {
      @-ms-keyframes #{$name} {
      @content;
    }
  }
  @if $o {
      @-o-keyframes #{$name} {
      @content;
    }
  }
  @keyframes #{$name} {
    @content;
  }
}

@include keyframes(foo) {
  0% {
    opacity:0;
  }
  100% {
    opacity:1;
  }
}
/* CSS コンパイル後*/
@-webkit-keyframes foo {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes foo {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

補完(インターポレーション)

Sassは補完を行うための構文として #{} を用意しています。

変数に入った文字列は通常は値として認識されてエラーが出てしまうため、そのままだとプロパティの値にしか使用できませんが、 シャープ記号を前に置いた波括弧 #{}と組み合わせることでセレクタやプロパティ名にも使うことができるようになります。

以下のように記述するとエラーになってしまいます。

//SASS (.scss)
$className: item;

p.$className {  //エラーになる
  color: red;
}

#{} を使って以下のように記述すれば、問題なくコンパイルされます。

//SASS (.scss)
$className: item;

p.#{$className} {
  color: red;
}
/* CSS コンパイル後*/
p.item {
  color: red;
}

以下の例ではエラーになりませんが、コンパイル後の CSS には何も出力されません。

//SASS (.scss)
$attr: border;

p {
  $attr-color: red; //正しいプロパティとして認識されない
}

この場合も #{} を使って以下のように記述すれば、問題なくコンパイルされます。

//SASS (.scss)
$attr: border;
 
p {
  #{$attr}-color: red;
}
/* CSS コンパイル後*/
p {
  border-color: red;
}

背景画像のパスを変数に入れて使用する場合の例です。

//SASS (.scss)
$img_path: "../common/images/foo/";

.icon {
  background: url($img_path + icon.gif) no-repeat;  //エラーになる
}

.icon {
  background: url(#{$img_path}icon.gif) no-repeat;  //OK
}

以下は演算しないようにする例です。

//SASS (.scss)
p.foo {
  $font-size: 16px;
  $line-height: 24px;
  font: $font-size/$line-height;  //演算されてしまう
}

p.bar {
  $font-size: 16px;
  $line-height: 24px;
  font: #{$font-size}/#{$line-height};  //演算しないようにする
}
/* CSS コンパイル後*/
p.foo {
  font: 0.66667;
}

p.bar {
  font: 16px/24px;
}

以下は演算できない場所で演算する例です。セレクタやプロパティ名に変数を使って演算をする場合に利用できます。

//SASS (.scss)
@for $i from 0 to 3 {
  .marginTop#{$i * 10} {
    margin-top: 10px * $i;
  }
}
/* CSS コンパイル後*/
.marginTop0 {
  margin-top: 0px;
}

.marginTop10 {
  margin-top: 10px;
}

.marginTop20 {
  margin-top: 20px;
}

制御構文(条件分岐・繰り返し)

Sassでは、条件分岐や繰り返し処理のための以下のような構文をサポートしています。

  • @if を使った条件分岐
  • if() 関数
  • @for を使った繰り返し処理
  • @while を使った繰り返し処理
  • @each でリストの要素に繰り返し処理
@if を使った条件分岐

@if は「もし~ならば、....を実行する」という構造を表現するためのもので、特定の条件を満たしている(true)場合にのみ処理を実行する構文です。

@if 条件 {
  条件にあっている場合に実行する処理
}

@else を使って、条件を満たしていない(false)場合の処理を設定することもできます。

@if 条件 {
  条件にあっている(true)場合に実行する処理
}@else {
    条件にあっていない(false)場合に実行する処理
}

更に条件にあっていない場合に、@else if を使って更に別の条件を追加することもできます。

@if 条件1 {
  条件1にあっている場合に実行する処理
}@else if 条件2 {
    条件1にあっていない場合で、条件2にあっている場合に実行する処理
}@else {
    条件1、条件2にあっていない場合に実行する処理
}

以下は、IE をサポートする場合は、「*zoom: 1;」を出力し、IE をサポートしない場合は出力しない条件分岐の例です。

条件分岐の判定には、$supportIE という変数(名前は任意)を用意して、サポートする場合は true を設定します。

//SASS (.scss)
$supportIE: true;  //IE をサポートする場合

.clearfix {
  @if $supportIE {
    *zoom: 1;
  }
  &:after {
    content: "";
    display: table;
    clear: both;
  }
}
/* CSS コンパイル後 IE をサポートする場合*/
.clearfix {
  *zoom: 1;
}
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

IE をサポートしない場合は、$supportIE に false を設定します。

このように、条件分岐を使うとサイトの用件によりスタイルを変更することができます。

//SASS (.scss)
$supportIE: false;  //IE をサポートしない場合

.clearfix {
  @if $supportIE {
    *zoom: 1;
  }
  &:after {
    content: "";
    display: table;
    clear: both;
  }
}
/* CSS コンパイル後 IE をサポートしない場合*/
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

@else if や @else を組み合わせることで条件を増やすことが可能です。

//SASS (.scss)
$type: tree;
 
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == fire {
    color: red;
  } @else if $type == tree {
    color: green;
  } @else {
    color: black;
  }
}

この例の場合、$type: tree; と宣言されているので、条件「$type == tree」が真(true)になり、以下のようにコンパイルされます。

/* CSS コンパイル後*/
p {
  color: green;
}

「==」は等しいという意味の比較演算子です。

以下は、@if で使える比較演算子と論理演算子です。

@if で使える比較演算子と論理演算子
演算子 説明
A==B AとBは等しい
A>B AはBより大きい
A<B AはBより小さい
A>=B AはB以上
A<=B AはB以下
A!=B AとBは等しくない
and かつ
or または
not 否定

「&& 」や「||」は Sass では使用できません。

if() 関数

if() は制御構文ではなく関数ですが、条件分岐で使用することができます。以下が構文です。

if($condition, $if-true, $if-false);
//if(条件式, 真の時の値, 偽の時の値);

if() は条件式が真(true)の場合は、「真の時の値」を返し、偽(false)の場合は「偽の時の値」を返す関数です。

以下のようなコードの場合、if() を使うと簡潔に書くことができます。(三項演算子に似ています)

//SASS (.scss)
$width: 200px;

.foo  {
  @if($width > 300px) {
    padding: 10px;
  } @else {
    padding: 5px;
  }
}
//SASS (.scss)
$width: 200px;

.foo  {
  padding: if($width > 300px, 10px, 5px);
}
/* CSS コンパイル後*/
.foo {
  padding: 5px;
}
@for を使った繰り返し処理

@for は、あらかじめ指定された回数だけ繰り返し処理を実行します。@for には以下の2つの構文があります。

繰り返しの処理は、from で指定した「開始の数値」から through または to で指定した「終了の数値」まで値を1つずつ増やしながら行われます。

@for ~ through

指定した終了の数値を含んで繰り返し処理

//SASS (.scss)
@for $変数名 from 開始の数値 through 終了の数値 {
  処理を記述
}

@for ~ to

指定した終了の数値を含まずに繰り返し処理

//SASS (.scss)
@for $変数名 from 開始の数値 to 終了の数値 {
  処理を記述
}

以下は @for ~ through の例です。「through」なので、1,2,3 がカウンタ変数「$i」に代入されて処理が実行されます。

カウンタ変数の名前は任意に付けることができます。また、クラス名にもインターポレーションを使って、カウンタ変数の値を利用しています。

//SASS (.scss)
@for $i from 1 through 3 {
  .item-#{$i} { width: 2em * $i; }
}
/* CSS コンパイル後*/
.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}
.item-3 {
  width: 6em;
}

カウンタ変数は1ずつ増加しますが、以下のように演算を利用することにより10ずつ増やすこともできます。以下は @for ~ to の例です。

//SASS (.scss)
@for $value from 1 to 5 {
  .marginTop_#{$value * 10} {
    margin-top: 10px * $value;
  }
}

「to」なので、1,2,3,4 がカウンタ変数「$value」に代入されて処理が実行されます。

/* CSS コンパイル後*/
.marginTop_10 {
  margin-top: 10px;
}
.marginTop_20 {
  margin-top: 20px;
}
.marginTop_30 {
  margin-top: 30px;
}
.marginTop_40 {
  margin-top: 40px;
}
@while を使った繰り返し

@while は、与えられた条件が true(真)である間、ループを繰り返します。以下が書式です。

//SASS (.scss)
@while 繰り返しを継続する条件 {
  スタイルなどの指定(処理を記述)
  繰り返しの条件を設定
}

@while では、「繰り返しを継続する条件」がどこかの時点で false(偽)になるように繰り返しの条件を設定します。

以下は前述の例(@for ~ to)を @while で記述した例です。

//SASS (.scss)
$value: 10;

@while $value < 50 {
  .marginTop_#{$value} {
    margin-top: $value + px;
  }
  $value: $value + 10;
}

$value は10ずつ増加して、50に達すると終了します。

/* CSS コンパイル後*/
.marginTop_10 {
  margin-top: 10px;
}
.marginTop_20 {
  margin-top: 20px;
}
.marginTop_30 {
  margin-top: 30px;
}
.marginTop_40 {
  margin-top: 40px;
}
@each でリストやマップの要素に繰り返し処理

リストは複数のデータ(値)をカンマやスペース、カッコで区切ったものです。以下はいずれも同じ値を持つリストです。

//SASS (.scss)
$list : foo, bar, baz;
$list : foo bar baz;
$list : (foo) (bar) (baz);

@each を使うと、リストの各要素に対して記述した処理を実行することができます。以下が構文です。

//SASS (.scss)
@each $変数名 in リスト {
  実行する処理
}

以下は、@each を使って top, about, contact と言うクラスにそれぞれ異なる背景画像を指定する例です。

//SASS (.scss)
$classList: top, about, contact;

@each $class in $classList {
  .#{$class} {
    background-image: url(../images/bg_#{$class}.png);
  }
}
/* CSS コンパイル後*/
.top {
  background-image: url(../images/bg_top.png);
}

.about {
  background-image: url(../images/bg_about.png);
}

.contact {
  background-image: url(../images/bg_contact.png);
}

以下は、リストの n 番目の値を取得する nth() 関数とリストの中の特定の値のインデックスを返す index() 関数です。

nth() 関数

リスト($list)の n 番目($n)の値を取得する
書式: nth($list, $n)

index() 関数

リスト($list)の中の特定の値($value)のインデックスを返す
書式: index($list, $value)

関連項目:リスト関連の関数

以下のような HTML があり、クラスにより文字色を設定する場合の例です。

<ul>
  <li class="top_color"><a href="#">HOME</a></li>
  <li class="about_color"><a href="#">ABOUT</a></li>
  <li class="contact_color"><a href="#">CONTACT</a></li>
</ul>

クラス名と対応する色の値のリストを用意して、@each を使ってクラスごとに文字色を設定する例です。

//SASS (.scss)
$classList: top, about, contact;  //クラス名のリスト
$color: #446D9E, #489069, #E36707;  //色の値のリスト

ul{
  li{
    @each $class in $classList{
      $index_key: index($classList, $class);  //インデックスを取得
      &.#{$class}_color{
        a{
          color: nth($color, $index_key);
          //取得したインデックスで n 番目の色を指定
        }
      }
    }
  }
}
/* CSS コンパイル後*/
ul li.top_color a {
  color: #446D9E;
}
ul li.about_color a {
  color: #489069;
}
ul li.contact_color a {
  color: #E36707;
}

@each でマップの要素に繰り返し処理

マップは任意の名前(キー)と値のペアが集まったものです。リストは値の集合ですが、マップはの各要素をコロン(:)区切りで名前(キー)と値のペアで記述した連想配列のようなものです。

リストとは異なり、括弧は省略できず、区切りもカンマに限られます。(Sass 3.3で追加)

//SASS (.scss)
$map: (
    key1: value1,  // key1にvalue1を設定
    key2: value2,
    key3: value3,
);

//以下のように記述しても同じ
$map: (key1: value1, key2: value2, key3: value3,);

@each を使って、マップの各要素(キーと値)に対して処理を実行することができます。以下が構文です。

//SASS (.scss)
@each $キーの変数名, $値の変数名 in マップ {
  実行する処理
}

前述の例は、マップを利用すると簡単に記述できます。

//SASS (.scss)
$classColorMap: (top:#446D9E, about:#489069, contact:#E36707);

ul{
  li{
    @each $class, $color in $classColorMap{
      &.#{$class}_color{
        a{
          color: $color;
        }
      }
    }
  }
}
/* CSS コンパイル後*/
ul li.top_color a {
  color: #446D9E;
}
ul li.about_color a {
  color: #489069;
}
ul li.contact_color a {
  color: #E36707;
}

関数

Sass には予め用意された関数があります。関数とは、定められた一連の処理(機能)を定義して名前を付けたもので、その関数を呼び出すことで一連の処理が実行される仕組みになっています。

Sass の関数は「Module: Sass::Script::Functions 」にリストされてます。

数値関連の関数

数値関連の関数には、以下のようなものがあります。(この他にもあります)

関数 意味
round($number) 小数点以下を四捨五入 round(10.6px) => 11px
ceil($number) 小数点以下を切り上げ ceil(10.4px) => 11px
floor($number) 小数点以下を切捨て floor(10.6px) => 10px
abs($number) 絶対値を返す abs(-10px) => 10px
percentage($number) パーセント形式に変換 percentage(100px / 50px) => 200%
min($numbers…) 最小の数値を返す min(5em, 3em, 4em) => 3em
max($numbers…) 最大の数値を返す max(5em, 3em, 4em) => 5em

以下は使用例です。

//SASS (.scss)
$width: 100%;

div {
  width: $width / 3;
}

.foo {
  width: ceil($width / 3);  //切り上げ
}

.bar {
  width: floor($width / 3);  //切捨て
}

.baz {
  width: round($width / 3);  //四捨五入
}
/* CSS コンパイル後*/
div {
  width: 33.33333%;
}

.foo {
  width: 34%;
}

.bar {
  width: 33%;
}

.baz {
  width: 33%;
}
色関連の関数

Sass には多数の色の関数がありますが、以下はその一部です。

関数 意味
rgba($color, $alpha) RGB値に透明度を指定 rgba(blue, 0.2) => rgba(0, 0, 255, 0.2)
lighten($color, $amount) 明るい色を作成 lighten(#800, 20%) => #e00
darken($color, $amount) 暗い色を作成 darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
mix($color1, $color2, [$weight]) 中間色を作成 mix(#f00, #00f, 25%) => #3f00bf
saturate($color, $amount) 彩度の高い色を作成 saturate(#855, 20%) => #9e3f3f
desaturate($color, $amount) 彩度の低い色を作成 desaturate(#855, 20%) => #726b6b

RGB 値に透明度を指定して RGBA 形式に変換

CSS では16進数の RGB 値に透明度を指定することはできませんが、Sass ではこれを自動的に変換してくれる rgba() という関数があります。

rgba($color, $alpha) の形式で、$color には色を16進数の RGB 値やキーワードで指定して、$alpha には透明度を指定します。(CSS では、このような形式で指定することはできません。)

//SASS (.scss)
.foo {
  background: rgba(#8D9EB8, 0.7);
}

.bar {
  background: rgba(orange, 0.3);
}
/* CSS コンパイル後*/
.foo {
  background: rgba(141, 158, 184, 0.7);
}

.bar {
  background: rgba(255, 165, 0, 0.3);
}

色を明るく/暗くする関数

Sass には色を明るくしたり、暗くする関数があります。グラデーションなどに便利です。

lighten($color, $amount)
darken($color, $amount)

$color には色を指定します。16進数の RGB 値や rgb(), hsl(), キーワードなどで指定します。$amount は割合を %( 0%~100%)で指定します。

//SASS (.scss)
.foo {
  background: lighten(#000, 30%);
}

.bar {
  background: darken(hsl(25, 100%, 80%), 20%);
}

$bg_color: #999;

.baz {
  background: darken($bg_color, 25%);
}

div {
  background-image :linear-gradient($bg_color, darken($bg_color, 20%));
}
/* CSS コンパイル後*/
.foo {
  background: #4d4d4d;
}

.bar {
  background: #ff8833;
}

.baz {
  background: #595959;
}

div {
  background-image: linear-gradient(#999999, #666666);
}

$amount の値が正の場合は明るくし、負の場合は暗くするオリジナル関数も定義することができます(オリジナル関数の定義 を参照)。

中間色を作成

mix() は2つの色の間の色を作成します。デフォルトではそれぞれの色の中間(50%)の色を作成します。

mix($color1, $color2, [$weight:50%])

$color1, $color2 には色(16進数RGB, rgb(), hsl()等)を指定します。$weight(割合)はオプションで、第一引数の割合を指定します(デフォルトは50%)。例えば 25% と指定すると、第一引数の色の割合が25%で第二引数の色の割合が75%になります。

また、透明度を指定することもできます。

//SASS (.scss)
.foo {
  background: mix(pink, red, 65%);
}
/* CSS コンパイル後*/
.foo {
  background: #ff7d84;
}
Pink
Red
#ff7d84

同系色の間の色はある程度予想できますが、色相の異なる色の場合は少し予想が難しいです。

//SASS (.scss)
.foo {
  background: mix(rgba(#70B1ED, 0.8), #F7B03B);
}
/* CSS コンパイル後*/
.foo {
  background: rgba(193, 176, 130, 0.9);
}
#70B1ED
#F7B03B
rgba(...)

彩度の高く/低くする関数

Sass には彩度を高くしたり、低くする関数もあります。

saturate($color, $amount)
desaturate($color, $amount)

$color には色を指定します。16進数の RGB 値や rgb(), hsl(), キーワードなどで指定します。$amount は割合を %( 0%~100%)で指定します。

彩度が低いほど灰色に近くなり、高いほど純色に近くなります。(参考:HSL / HSLA

//SASS (.scss)
$bg_color: #49B462;

.foo {
  background-color: $bg_color;
}

.bar {
  background-color:saturate($bg_color, 20%);  //彩度を20%高く
}

.baz {
  background-color:desaturate($bg_color, 20%);  //彩度を20%低く
}
/* CSS コンパイル後*/
.foo {
  background-color: #49B462;
}

.bar {
  background-color: #30cd55;
}

.baz {
  background-color: #629b6f;
}
foo #49B462
bar #30cd55
baz #629b6f
文字列関連の関数

Sass には以下のような文字列関連の関数があります。

関数 意味
unquote($string) クォーテーションを取り除く unquote("foo") => foo
quote($string) クォーテーションを加える quote(foo) => "foo"
str-length($string) 文字列の長さを返す str-length("foo") => 3
str-insert($string, $insert, $index) 指定した位置に文字列を挿入 str-insert("abcd", "X", 4) => "abcXd"
str-index($string, $substring) 指定した文字列の開始位置を返す str-index(abcd, c) => 3
str-slice($string, $start-at) 指定した範囲を取り出す str-slice("abcd", 2) => "bcd"
to-upper-case($string) 文字列を大文字に変換 to-upper-case(abcd) => ABCD
to-lower-case($string) 文字列を小文字に変換 to-lower-case(ABCD) => abcd

指定した位置に文字列を挿入

str-insert()は、文字列($string)の中の指定した位置($index)に指定した文字列($insert)を挿入する関数です。

str-insert($string, $insert, $index)

Sass では、最初の文字のインデックスは 1 になります(0 ではありません)。

//SASS (.scss)
str-insert("abcd", "X", 1) => "Xabcd"
str-insert("abcd", "X", 4) => "abcXd"
str-insert("abcd", "X", 5) => "abcdX"

第3引数の位置($index)には負の値を指定することができます。その場合、文字列の末尾からの位置になります。

//SASS (.scss)
str-insert("abcd", "X", -1) => "abcdX"
str-insert("abcd", "X", -4) => "aXbcd"

指定した文字列の開始位置を返す

str-index()は、文字列($string)の中に指定された文字列($substring)が含まれている場合は開始位置を返し、含まれていない場合は0を返します。

str-index($string, $substring)

Sass では、最初の文字のインデックスは 1 になります(0 ではありません)。

//SASS (.scss)
str-index(abcd, a)  => 1
str-index(abcd, ab) => 1
str-index(abcd, X)  => null
str-index(abcd, c)  => 3

文字列から指定した範囲を取り出す

str-slice()は、文字列($string)から指定した範囲($start-at~$end-at)を取り出す関数です。

第3引数($end-at)はオプションで、省略すると範囲は末尾までになります。デフォルトの値は「-1」です。

str-slice($string, $start-at, [$end-at])

Sass では、最初の文字のインデックスは 1 になります(0 ではありません)。

//SASS (.scss)
str-slice("abcd", 2, 3)   => "bc"
str-slice("abcd", 2)      => "bcd"
str-slice("abcd", -3, -2) => "bc"
str-slice("abcd", 2, -3)  => "b"

第2引数($start-at)、第3引数($end-at)に負の値を指定すると、末尾からの位置になります。

リスト(List)関連の関数

リスト関連の関数には以下のようなものがあります。

関数 意味
length($list) 項目数を取得 length(10px 20px 30px) => 3
nth($list, $n) n番目の項目を取得 nth(10px 20px 30px, 1) => 10px
index($list, $value) 項目が何番目にあるかを返す index(1px solid red, solid) => 2
set-nth($list, $n, $value) n番目の要素を置き換え set-nth(10px 20px 30px, 2, -20px) => 10px -20px 30px
join($list1, $list2, [$separator]) リストを結合 join(10px, (20px 30px)) => 10px 20px 30px
append($list1, $val, [$separator]) リストの末尾に追加 append((blue, red), green) => blue, red, green

Sass では、最初のインデックスは 1 になります(0 ではありません)。

n番目の項目を取得

nth($list, $n) はリストの n 番目の項目(の値)を返します。第2引数に負の値を指定した場合は、文字列の末尾からのカウントします。

//SASS (.scss)
$list: foo, bar, baz;
nth($list, 2) => bar
nth($list, -1) => baz

使用例は @each でリストやマップの要素に繰り返し処理 も参照ください。

リストの中の指定した値の位置を返す

index($list, $value) はリスト($list)の中の指定した値($value)の位置を返します。

//SASS (.scss)
index(1px solid red, solid) => 2
index(1px solid red, dashed) => null
index((width: 10px, height: 20px), (height 20px)) => 2

指定した値がない場合は null が返ります。

n番目の要素を置き換え

set-nth($list, $n, $value) はリストの n 番目の項目を指定した値($value)で置き換えます。元のリストは変更されません。

第2引数の位置($n)に負の値を指定すると、文字列の末尾からのカウントします。

//SASS (.scss)
$list: 10px 20px 30px 40px;

.foo {
  margin: set-nth($list, 2, -20px);
}
.bar {
  margin: set-nth($list, -2, -50px);
}
.baz {
  margin:$list;
}
/* CSS コンパイル後*/
.foo {
  margin: 10px -20px 30px 40px;
}
.bar {
  margin: 10px 20px -50px 40px;
}
.baz {
  margin: 10px 20px 30px 40px;
}

リストを結合

join($list1, $list2, [$separator]) は2つのリストを結合します。オプションでセパレータ(区切り文字)を指定することができます。

セパレータ(区切り文字)を指定しない場合は、自動的に第1引数のリストのセパレータが使用されます。但し、両方のリストの項目が1つ以下の場合はスペースが使用されます。

また、元のリストは変更されません(全てのリスト関連の関数で共通)。

//SASS (.scss)
$list1: foo, bar, baz;
$list2: aaa bbb ccc;
.sample {
    &:before {
        content: "#{join($list1, $list2)}";
    }
}
/* CSS コンパイル後*/
.sample:before {
  content: "foo, bar, baz, aaa, bbb, ccc";
}

リストの末尾に項目(値)を追加

append($list1, $val, [$separator]) はリストの末尾に項目(値)を追加します。オプションでセパレータ(区切り文字)を指定することができます。

リストの項目が1つだけで、セパレータ(区切り文字)を指定しない場合はスペースが使用されます。

//SASS (.scss)
append(10px 20px, 30px) => 10px 20px 30px
append((blue, red), green) => blue, red, green
append(10px 20px, 30px 40px) => 10px 20px (30px 40px)
append(10px, 20px, comma) => 10px, 20px
append((blue, red), green, space) => blue red green

以下は、要素が1つしかないリスト($list)を作成し、要素を追加する例です。$list の要素の後にカンマ(,)がないと、スペース区切りのリストとして扱われてしまいます。

//SASS (.scss)
$list: (10px 5px 5px #8D9EB8,);
$extra: 20px 10px 10px #B0F5C9;

.foo {
  box-shadow: append($list, $extra, comma);
}

.bar{
  box-shadow: $list;
}
/* CSS コンパイル後*/
.foo {
  box-shadow: 10px 5px 5px #8D9EB8, 20px 10px 10px #B0F5C9;
}

.bar {
  box-shadow: 10px 5px 5px #8D9EB8;
}
マップ(map)関連の関数

マップは任意の名前(キー)と値のペアが集まったものです。

キーと値のペアをコロン(:)区切りで記述します。また、リストとは異なり、括弧は省略できず、区切りもカンマに限られます。(Sass 3.3で追加)

マップの値は、データ型を問わずどのようなデータ型でも記述することができ、マップやリストを指定してネストすることも可能です。

以下は、クラスごとの背景色のマップの例です。

$class_colors: (
  home: #E8E4E4,
  about: #EFF6FB,
  contact: #E4F8EF,
  news: #F8FBE3
);

@each 構文と上記のマップを使うと簡単に各クラスの背景色を書き出すことができます。

//SASS (.scss)
$class_colors: (
  home: #E8E4E4,
  about: #EFF6FB,
  contact: #E4F8EF,
  news: #F8FBE3
);

@each $class, $color in $class_colors {
  .#{$class} {
    background-color: $color;
  }
}
/* CSS コンパイル後*/
.home {
  background-color: #E8E4E4;
}
.about {
  background-color: #EFF6FB;
}
.contact {
  background-color: #E4F8EF;
}
.news {
  background-color: #F8FBE3;
}

マップの関数を使うと、キーを指定して値を取得したり、全てのキーや値を取得することなどができます。以下がマップの関数です。

関数 意味
map-get($map, $key) 指定したキーの値を取得 map-get(("foo": 1, "bar": 2), "foo") => 1
map-merge($map1, $map2) 2つのマップをマージ map-merge(("foo": 1), ("bar": 2)) => ("foo": 1, "bar": 2)
map-remove($map, $keys…) 指定したキーのペアを削除 map-remove(("foo": 1, "bar": 2), "bar") => ("foo": 1)
map-keys($map) すべてのキーを取得 map-keys(("foo": 1, "bar": 2)) => "foo", "bar"
map-values($map) すべての値を取得 map-values(("foo": 1, "bar": 2)) => 1, 2
map-has-key($map, $key) 特定のキーがあるかを調べる map-has-key(("foo": 1, "bar": 2), "foo") => true

指定したキーの値を取得

map-get($map, $key) は指定したキー($key)の値を取得します。

指定したキーが存在しない場合は、null(空の値)を返します。

//SASS (.scss)
$sample: ("foo": #FFF, "bar": #000, "baz": #CCC);

.sample1 {
  color:map-get($sample, "foo");  // => #FFF
}
.sample2 {
  color:map-get($sample, "bar");  // => #000 
}
.sample3 {
  color:map-get($sample, "xxx");  // => null 
}
/* CSS コンパイル後*/
.sample1 {
  color: #FFF;
}
.sample2 {
  color: #000;
}
/*.sample3 は null なのでプロパティは書き出されません。*/

2つのマップをマージ

map-merge($map1, $map2) は2つのマップをマージします。既存のマップに値を追加して新しいマップを生成します。

1つ目のマップの後に、2つ目のマップが追加されます。それぞれのマップのキー・値の順番は保たれます。但し、もし同じキーがある場合は2つ目のマップの値で上書きされます。

//SASS (.scss)
$map1: (foo:1, bar:2, baz:3,);

$map2: (aaa:4, bbb:5, foo:6,);

$map3: map-merge($map1, $map2);

//$map3 => (foo:6, bar:2, baz:3, aaa:4, bbb:5);

上記の例の場合、同じキー(foo)が存在するので、foo の値は2つ目のマップの値で上書きされます。

指定したキーのペアを削除

map-remove($map, $keys…) は指定したキー($keys…)とその値を削除し、新しいマップを生成します。複数のキーを指定することが可能です。

//SASS (.scss)
$map: (foo:1, bar:2, baz:3);

$map1: map-remove($map, foo);  // (bar:2, baz:3,)

$map2: map-remove($map, bar, baz); // (foo:1)

すべてのキーを取得

map-keys($map) は指定したマップ($map)のすべてのキーをカンマ区切りのリストで返します。

//SASS (.scss)
$map: (foo:1, bar:2, baz:3);

.map {
    content: map-keys($map);
}
/* CSS コンパイル後*/
.map {
  content: foo, bar, baz;
}

すべての値を取得

map-values($map) は指定したマップ($map)のすべての値をカンマ区切りのリストで返します。

//SASS (.scss)
$map: (foo:1, bar:2, baz:3);

.map {
    content: map-values($map);
}
/* CSS コンパイル後*/
.map {
  content: 1, 2, 3;
}

特定のキーがあるかを調べる

map-has-key($map, $key) は指定したマップ($map)内に特定のキー($key)があるかどうか調べます。

指定したキーが存在すれば true を返し、存在しなければ false を返します。

//SASS (.scss)
map-has-key(("foo": 1, "bar": 2), "foo") => true
map-has-key(("foo": 1, "bar": 2), "baz") => false
//SASS (.scss)
$map: (foo:#EEE, bar:#AAA, baz:#000);

p {
  @if map-has-key($map, foo) {
    color: map-get($map, foo);
  } @else {
    color: red;
  }
}
/* CSS コンパイル後*/
p {
  color: #EEE;
}
Introspection 関数

以下は、Introspection 関数の一部です。

関数 意味
inspect($value) デバッグ用
type-of($value) 値の型を返す type-of(100px) => number
unit($number) 値の単位を返す unit(3em) => "em"
unitless($number) 値に単位がついていないかどうか unitless(100) => true
comparable($number1, $number2) 値が合計したり比較したりできるか comparable(2px, 1px) => true

デバッグ用関数

inspect($value) は、デバッグ用の関数です。

通常は、CSS として有効でない値を指定するとコンパイルエラーになってしまいますが、inspect($value) を使うとそのような場合でも処理結果を文字列として出力してくれます。但し、CSS の形式で任意のセレクタを指定して波括弧の中に記述する必要があります。

以下は、inspect() を使って CSS の値にマップを指定して出力する例です。inspect() を使わないとコンパイルエラーになります。

//SASS (.scss)
$map: (foo:1, bar:2, baz:3);

.foo {
  content: inspect($map);
}
/* CSS コンパイル後*/
.foo {
  content: (foo: 1, bar: 2, baz: 3);
}

値の型を返す

type-of($value) は値の(データ)型を取得するのに使用します。

//SASS (.scss)
type-of(100px)  => number
type-of(asdf)   => string
type-of("asdf") => string
type-of(true)   => bool
type-of(#fff)   => color
type-of(blue)   => color

値の単位を返す

unit($number) は値の単位を取得するのに使用します。返される単位はアルファベット順に表示されます。

//SASS (.scss)
unit(100) => ""
unit(100px) => "px"
unit(3em) => "em"
unit(10px * 5em) => "em*px"
unit(10px * 5em / 30cm / 1rem) => "em/rem"
/*SASS のサイトでは上記は "em*px/cm*rem" を返すように書かれていますが、
実際には異なるようです。*/

値に単位がついていないかどうか

unitless($number) は値に単位がついていないかどうかを調べ、付いていなければ true を、付いていれば false を返します。

//SASS (.scss)
unitless(100) => true
unitless(100px) => false
//SASS (.scss)
$val: 100;

@if(unitless($val)) {
  $val: $val + "px";
}

.foo {
  width: $val ;
}
/* CSS コンパイル後*/
.foo {
  width: "100px";
}

値が合計したり比較したりできるか

comparable($number1, $number2) は2つの値(数値)が、合計したり比較したりできるかどうかを調べ、合計したり比較したりできる場合は true を、そうでない場合は false を返します。

//SASS (.scss)
comparable(2px, 1px) => true
comparable(100px, 3em) => false
comparable(10cm, 3mm) => true
オリジナル関数の定義

@function を使って、自分で独自の function(関数)を定義することができます。以下が構文です。

@function 関数名($引数) {
  // 処理の記述(必要であれば)
  @return 戻り値;
}

@function で関数の宣言をします。独自の関数名を指定して、引数を設定し、@return を使って戻り値を返します。引数は必須ではありません。

関数名は任意の名前を付けられますが、Sass や CSS で定義されている関数と同じ名前は使えません。そのため独自関数の名前には接頭辞を付けることが推奨されています。

以下はサイズを変更する独自関数の例です。

//SASS (.scss)
@function _changeSize($value, $size) {
  @return $value * $size;
}

.foo {
  width: _changeSize(200px, 1/3) ;
}
.bar {
  height: _changeSize(50px, 1.6);
}
/* CSS コンパイル後*/
.foo {
  width: 66.66667px;
}

.bar {
  height: 80px;
}

独自関数の中では、Sass の関数を利用することができます。以下は前述の関数に Sass の切捨ての関数(floor())を利用した例です。

//SASS (.scss)
@function _changeSize($value, $size) {
  @return floor($value * $size);
}

.foo {
  width: _changeSize(200px, 1/3) ;
}
/* CSS コンパイル後*/
.foo {
  width: 66px;
}

以下は、グリッドとその間隔の幅を変数として定義して、引数にカラム数を指定すると幅を算出する関数の例です。

幅の計算は以下の式で求められるます

幅 = (カラム数 × グリッドの幅) + ((カラム数 – 1) × 間隔の幅)

//SASS (.scss)
$grid-width: 60px;
$gutter-width: 20px;

@function _grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

.container {
  width: _grid-width(12);
  margin: 0 auto;

  .main {
    width: _grid-width(8);
    float: left;
    margin-right: $gutter-width;
  }

  .sidebar {
    width: _grid-width(4);
    float: left;
    margin-right: $gutter-width;
  }
}
/* CSS コンパイル後*/
.container {
  width: 940px;
  margin: 0 auto;
}
.container .main {
  width: 620px;
  float: left;
  margin-right: 20px;
}
.container .sidebar {
  width: 300px;
  float: left;
  margin-right: 20px;
}

コメント

独自に定義した関数の場合、その関数がどのようなものなのかをコメントとして残しておくと便利です。引数の型や単位が必要か等を記述するようにすると良いと思います。

//SASS (.scss)
// @function _linearGradient グラデーションの値を返す
// @param    {Color} $baseColor
// @param    {Number} percentage 0-100% default: 20%
// @return   {String} linear-gradient valuse

@function _linearGradient($baseColor, $amount: 20%) {
  @return "linear-gradient(" + $baseColor + "," + darken($baseColor, $amount) + ")";
}

.foo {
  background-image :_linearGradient(#CCCCCC);
}

上記の例では、第2引数に初期値を設定しています。

/* CSS コンパイル後*/
.foo {
  background-image: "linear-gradient(#CCCCCC,#999999)";
}

明るさを調整する関数

Sass には色を明るく/暗くする関数が用意されていますが、以下はパラメータの $amount の値が正の場合は明るくし、負の場合は暗くする独自関数の例です。(Compass にはこのような関数が用意されています)

//SASS (.scss)
// @function _changeLightness 色の明るさを調整して返す
// @param    {Color} $color
// @param    {Number} $amount -100%~100% 
// @return   {Color} color valuse
@function _changeLightness($color, $amount) {
  @if unitless($amount) {
    $amount: 1% * $amount;
  }
  @if $amount > 0 {
    @return lighten($color, $amount);
  }@else {
    @return darken($color, abs($amount));
  }
}
.foo {
  color: _changeLightness(#999, -20%);
}
/* CSS コンパイル後*/
.foo {
  color: #666666;
}

@debug / @warn / @error

@debug, @warn, @error は関数やミックスインのテストやデバッグに使用するもので、コマンドプロンプトの画面にメッセージを表示してくれます。

@debug 出力の確認

@debug を使うと、値をコマンドプロンプトの画面に出力することができます。どのような値が出力されるかを確認するのに使用できます。

以下は単純に「10em + 3em * 4;」の結果を出力する例です。

//SASS (.scss)
@debug 10em + 3em * 4;

以下のように、ファイル名(style.scss)に続き、行番号(2)と出力結果(22em)がコマンドプロンプトの画面に表示されます。

// コマンドプロンプト
style.scss:2 DEBUG: 22em

以下は関数 join() の出力結果を表示する例です。

//SASS (.scss)
$list1: foo, bar, baz;
$list2: aaa bbb ccc;
@debug join($list1, $list2);
// コマンドプロンプト
style.scss:4 DEBUG: foo, bar, baz, aaa, bbb, ccc

デバッグ用関数 inspect() は通常ではコンパイルエラーになるような値を CSS に出力してくれます。

関数などを作成する際に、思うようにいかない場合など、途中で値を出力して確認することができます。

//SASS (.scss)
@function _myMixColor($color1, $color2) {
  $mixColor1: ($color1 + $color2);
  @debug $mixColor1;
  $mixColor2: $mixColor1/2;
  @debug $mixColor2;
  @return $mixColor2;
}

.foo {
  color: _myMixColor(#999999, #AAAAAA);
}
// コマンドプロンプト
style.scss:4 DEBUG: white
style.scss:6 DEBUG: gray
@warn 警告の表示

@warn を使用するとユーザーが誤った使い方や推奨されない使い方等をした場合に、任意の警告のメッセージをコマンド画面に表示させる事が出来ます。

@warn はそれが発生した箇所をファイル名と行数、関数名を表示してくれます。

警告を表示する箇所に「@warn "任意のメッセージ";」を記述します。

以下は、ミックスインの引数に単位(px)を付けないで使用した場合に警告メッセージを表示する例です。このミックスインは単位を付けなくても問題なく機能しますが、適切な使い方をユーザーに知らせるための警告になっています。

また、メッセージは文字列なのでその中で変数を表示するにはインターポレーションを利用します。

//SASS (.scss)
@mixin adjust-location($x, $y) {
  @if unitless($x) {
    @warn "Assuming #{$x} to be in pixels";
    $x: 1px * $x;
  }
  @if unitless($y) {
    @warn "Assuming #{$y} to be in pixels";
    $y: 1px * $y;
  }
  position: relative; left: $x; top: $y;
}

.foo {
  @include adjust-location(10, 20);
}

警告は以下のように「WARNING:」に続けて指定した任意の文字列が表示されます。

// コマンドプロンプト
WARNING: Assuming 10 to be in pixels  //警告メッセージ
on line 4 of C:/.../sass/style.scss, in `adjust-location'
from line 15 of C:/.../sass/style.scss

WARNING: Assuming 20 to be in pixels //警告メッセージ
on line 8 of C:/.../sass/style.scss, in `adjust-location'
from line 15 of C:/.../sass/style.scss
/* CSS コンパイル後*/
.foo {
  position: relative;
  left: 10px;
  top: 20px;
}
@error エラーを発生

@error を使用すると、不適切な値が使用された場合などにエラーを発生させて処理を中断し、コマンドプロンプトにエラーメッセージを表示することができます。

以下は、引数に単位が付いていないと Fatal Error を発生させ処理を中止する例です。

//SASS (.scss)
@mixin adjust-location($x, $y) {
  @if unitless($x) {
    @error "$x には単位が必要です: #{$x}";
  }
  @if unitless($y) {
    @error "$y には単位が必要です: #{$y}";
  }
  position: relative; left: $x; top: $y;
}

.foo {
  @include adjust-location(10, 20);
}

上記の例では、引数に単位が付いていないのでフェータルエラーを発生させ処理を中断し、コマンドプロンプトに以下のメッセージを表示します。

また、4行目のエラーのみが表示されているのは、その時点で処理が中断しているためで、7行目まで到達していません。

// コマンドプロンプト
error sass/style.scss (Line 4: $x には単位が必要です: 10)

コンパイルエラーも発生します。

/* CSS コンパイル後*/
/*
Error: $x には単位が必要です: 10
    on line 4 of C:/.../sass/style.scss, in `adjust-location'
    from line 13 of C:/.../sass/style.scss
    ........

この例のミックスインの場合、@error を使わないと以下のようになります。

//SASS (.scss)
@mixin adjust-location($x, $y) {
  position: relative; left: $x; top: $y;
}

.foo {
  @include adjust-location(10, 20);
}

ミックスインの引数に単位を付けないで呼び出しても、以下のようにコンパイルされてしまいます。

/* CSS コンパイル後*/
.foo {
  position: relative;
  left: 10;   //単位なし
  top: 20;    //単位なし
}