Sassの書き方

Sassの書き方

Sass の概要

Sass とは、今までの CSS にプログラミング的な書き方を加えて、.scss ファイルを変換(コンパイル)することで .css ファイルを作成します。
例えば、「style.scss」を変換すると、「style.css」が作成されます。

大手様が Sass を導入しているという話をよく耳にするけれど

・・・一体何が便利なの?

ざっくり言いますと、Sass を導入する事で、記述が減りメンテナンス性が向上します!
結果的に、コーディングのスピードが抜群にUPできると言うしろものなのですっ

と・・・言葉で書いてもこの便利さがいまいちピンと来ないと思うので、インターネットに繋がっている環境(IE8 以上)なら誰でも簡単に Sass を体験することができるサイトをご紹介!

SassMister
※SASS 記法と SCSS記法 がありますが、「SCSS記法」が標準です。

次はこのサイトを使って、簡単に Sass の世界に触れてみましょう!!
まずは触れてみることが大事!きっとワクワクするはず・・・!

Sass の基本機能

ルールのネスト(Nested Rules)

ネストは、Sass の中でも一番よく使う機能で、CSS を HTML の構造に合わせて入れ子で書いて行くことができますっ

例:CSS の構造にあわせて入れ子にする場合

▼ Sass

1
2
3
4
5
6
7
8
9
10
11
12
#main section {
     margin-bottom: 50px;
     h1 {
          font-size: 140%;
     }
     p, ul {
          margin-bottom: 1.5em;
     }
     p.notes {
          color: red;
     }
}

▼ CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
#main section {
     margin-bottom: 50px;
}
 
#main section h1 {
     font-size: 140%;
}
#main section p, #main section ul {
     margin-bottom: 1.5em;
}
#main section p.notes {
     color: red;
}

入れ子にする事で、記述がスッキリしましたッ

親セレクタの参照 &(アンパサンド)

セレクタに「&」を書くことで親セレクタを参照できます。

例:類似クラスやクラス指定でやってみた

▼ Sass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a {
     text-decoration: none;
     &:hover {
          text-decoration: underline;
     }
}
 
ul.pageNav {
     li {
          margin: 0;
          width: 50%;
          &.prev {
               float: left;
          }
          &.next {
               float: right;
          }
     }
}

▼ CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a {
     text-decoration: none;
}
a:hover {
     text-decoration: underline;
}
 
ul.pageNav li {
     margin: 0;
     width: 50%;
}
ul.pageNav li.prev {
     float: left;
}
ul.pageNav li.next {
     float: right;
}

主な使いどころは、類似クラスやクラスの二重指定とか・・・!

プロパティのネスト(Nested Properties)

ネストはセレクタだけではなく、プロパティでも使うことができます!

例:background プロパティをネストしてみる

▼ Sass

1
2
3
4
5
6
7
.sample {
     background: {
          image: url(img/bg_head.jpg);
          repeat: no-repeat;
          position: center top;
     }
}

▼ CSS

1
2
3
4
5
.sample {
     background-image: url(img/bg_head.jpg);
     background-repeat: no-repeat;
     background-position: center top;
}

「-(ハイフン)」つなぎのプロパティは全てネストできるのですが、ややこしくなるので・・・っ
基本的には、一括指定ができるプロパティでのみ使うようにしましょう!

Sass で使えるコメント

下記の3つを使うことができますッ

○ 1行コメント

コンパイル後、CSS に出力されないコメントです!
納品をする際に残しておきたくないコメントがある場合に使いましょうッ

▼ Sass
1
2
3
4
5
.box {
     //width: 350px;
     min-height: 300px;
     _height: 300px; // IE6対策
}
▼ CSS
1
2
3
4
.box {
     min-height: 300px;
     _height: 300px;
}

○ 通常のコメント

基本的には、コンパイル後も CSS に出力されるコメントですが、出力される CSS ファイルのフォーマットが Compressed の場合はこちらのコメントは出力されません!

▼ Sass
1
2
3
4
5
6
7
.box {
     /*
     width: 350px;
     */
     min-height: 300px;
     _height: 300px; /* IE6対策 */
}
▼ CSS
1
2
3
4
5
6
7
8
.box {
     /*
     width: 350px;
     */
     min-height: 300px;
     _height: 300px;
     /* IE6対策 */
}

納品時、CSS に残して起きたいコメントがある場合に使うようにしましょう!

○ compressed でも残るコメント

出力される CSS ファイルのフォーマットがいかなるものでも、CSS に必ず吐き出されるコメントです!通常のコメントとの違いは「!」を入れている所ですっ

例:フォーマットを Compressed にした場合

▼ Sass
1
2
3
4
5
.box {
     /*! width: 350px; */
     min-height: 300px;
     _height: 300px; /* IE6対策 */
}
▼ CSS
1
.box{/*! width: 350px; */;min-height:300px;_height:300px}

出力されないと困る大事なコメントである場合に使いましょう!
WordPress のスタイルシートヘッダ、更新日、コピーライトなど・・・。

変数

あらかじめ、変数を定め値を使い回すことができます!

例:仕様書でカラーが決まっている場合

▼ Sass

1
2
3
4
5
6
7
8
9
$red: #cf2d3a;
 
.notes {
     color: $red;
}
 
.notesBox {
     border: 3px double $red;
}

▼ CSS

1
2
3
4
5
6
7
.notes {
     color: #cf2d3a;
}
 
.notesBox {
     border: 3px double #cf2d3a;
}

カラーが変更になった際に、修正は1箇所で済みますッ
・・・便利ですね!

演算

数値の算出に毎回電卓を叩いている方にオススメなのがコレ。

例:width の値から padding の値を引く場合

▼ Sass

1
2
3
4
article {
     width: 560px - 14px;
     padding: 7px;
}

▼ CSS

1
2
3
4
article {
     width: 546px;
     padding: 7px;
}

ミックスイン - Mixins

ミックスインは、プロパティやセレクタをまとめてワンセットにしておく事が可能で、それらをカンタンにインクルード(読み込む)する事が出来ます。
変数の機能を強化したと言うか便利にしたようなイメージです。

Sass

@mixin inline_block {
display: inline-block;
*display: inline;
*zoom: 1;
}

@mixinの後に半角スペース、任意の名前って感じで定義します。

この例では、display: inline-block; を IE でも使う場合に、 *display: inline; と *zoom: 1; を指定する必要があります。
これを毎回書くと面倒なので、ミックスインを使って予め定義しておくことで、次のように1行書くだけでインクルード出来ます。

Sass

.sampleBox {
@include inline_block;
background: #eee;
}

@includeの後に半角スペース、ミックスインで定義した名前って感じで記述します。
当然、他の宣言と一緒に書くことが可能です。
これを変換すると、、、

変換されたCSS

.sampleBox {
display: inline-block;
*display: inline;
*zoom: 1;
background: #eee;
}

無事にインクルードされ、展開されました。
こんな感じで、何度も使うようなスタイルや長めの宣言を予め定義してインクルード出来るので、かなりの工数削減になると思います。
特にCSS3使ってて、ベンダープレフィックスが多い場合とか。

このミックスインもかなり強力な機能なので、がっつりやり出すとかなり覚えたりやることが多いですが、いきなり複雑な事はせずに、この宣言何度も書いてるなーと思ったらミックスインで定義しておく位が最初は良いのかなと。

ちなみに、この inline-block程度ならミックスインではなく次に説明する セレクタを継承出来る @extend を使った方が良いかもです。

この他にもミックスインは、変数と合わせたり初期値を指定したり、とても色んな事が出来ますが、もうちょっと詳しい説明は後のエントリーで書く予定です(ちゃんと書けよ自分)。

セレクタの継承 - Selector Inheritance(@extend)

@extend は、一度使ったセレクタを継承して使うことが出来ます。
ミックスインと似てる部分も多いのですが、似て非なるものって感じで用途がだいぶ変わってきます。
文だと伝わる気がしないので、例を見てください。

Sass

.imgR {
float: right;
margin-left: 10px;
margin-bottom: 1.5em;
}

これだけ見ても、いつものCSSと何ら変わりは有りませんが、この一度使ったセレクタを使うことが出来ます。

Sass

.photo {
@extend .imgR;
}

と書くことで .imgR で指定した宣言が .photo でも継承されます。
これを変換すると、、、

変換されたCSS

.imgR, .photo {
float: right;
margin-left: 10px;
margin-bottom: 1.5em;
}

こんな感じで変換されるので、clearfix等のように一度使ったセレクタを再利用したい場合に便利な機能です。

ちなみに、clearfixを @extend で利用する場合はこんな感じです。

Sass

.clearfix {
*zoom: 1;
&:after {
content: ".";
display: block;
clear: both;
height: 0;
visibility: hidden;
}
}
 
ul.menu {
@extend .clearfix;
background: #ccc;
li {
float: left;
width: 100px;
}
}

変換されたCSS

.clearfix, ul.menu {
*zoom: 1;
}
.clearfix:after, ul.menu:after {
content: ".";
display: block;
clear: both;
height: 0;
visibility: hidden;
}
 
ul.menu {
background: #ccc;
}
ul.menu li {
float: left;
width: 100px;
}

clearfixから話を戻して。
また次のように、スタイルを上書きしたい場合も有ると思います。

Sass

.imgR {
float: right;
margin-left: 10px;
margin-bottom: 1.5em;
}
.photo {
@extend .imgR;
margin-left: 5px;
}

この様な場合は、次のようにちゃんと分けて変換してくれます。

変換されたCSS

.imgR, .photo {
float: right;
margin-left: 10px;
margin-bottom: 1.5em;
}
.photo {
margin-left: 5px;
}

部分的に、スタイルを上書きしたい場合も問題ないですね。
こんな感じで便利な @extend ですが、現状だと単独のセレクタしか使うことしか出来ません。
よく分からない説明ですが、次の場合はエラーになっちゃいます。

Sass(エラー)

.item .imgR {
float: right;
margin-left: 10px;
margin-bottom: 1.5em;
}
.photo {
@extend .item .imgR;
}

子孫セレクタとかセレクタを組み合わせるとダメって事ですね。
これは、将来的に対応されるのかな。

@extend は使い方に寄ってはミックスインでも何ら問題が無いのですが、大きな違いとして、ミックスインはインクルードする度に展開され、@extend はグループ化されて変換されます。
なので、例えばclearfixをミックスインで定義して、複数ヶ所でインクルードするとその数だけ宣言が増えていきますが、@extend だとグループ化されるのでより合理的なCSSになります。


// SCSS

// 継承元のセレクタ
.button {
    display: inline-block;
    border: 1px solid gray;
    background-color: silver;
    &:hover {
        border-color: black;
    }
}

// .button セレクタを継承・拡張
.button-download {
    @extend .button;         // .button を継承
    background-color: green; // プロパティを上書き
    border-radius: 4px;      // 新たなプロパティの追加
    .icon {                  // ネストしたセレクタの追加
        background: url(/img/download.png) no-repeat 0 50%;
    }
}

この SCSS をコンパイルすると、こういう CSS が生成されます:

/* CSS */

.button,
.button-download {
    display: inline-block;
    border: 1px solid gray;
    background-color: silver;
}

.button:hover,
.button-download:hover {
    border-color: black;
}

.button-download {
    background-color: green;
    border-radius: 4px;
}

.button-download .icon {
    background: url(/img/download.png) no-repeat 0 50%;
}

6) config.rb を用意する
sass ディレクトリ内に、config.rb データを作成します!
config.rb は、「Sass を制御するための設定ファイル」ですっ

ファイルを新規作成して、下記を記述します!

http_path = "/"
css_dir = "/"
sass_dir = "/"
images_dir = "images"
javascripts_dir = "javascripts"

 

 

2.変数入門

通常の言語同様グローバルスコープとローカルスコープが存在する。
変数の定義方法は下記の通り。

1
$width1 : 5em;

特に意識しなくても良いが、データ型は以下の5つがある。
numbers (e.g. 1.2, 13, 10px)
strings of text, with and without quotes (e.g. “foo”, ‘bar’, baz)
colors (e.g. blue, #04a3f9, rgba(255, 0, 0, 0.5))
booleans (e.g. true, false)
lists of values, separated by spaces or commas (e.g. 1.5em 1em 0 2em, Helvetica, Arial, sans-serif)

スタイルの外側で定義すればグローバルスコープとなりファイル全体で使用することができる。

1
2
3
4
5
6
7
8
9
10
11
$width1 : 5em;
#navbar {
 
  width: $width1;
  height: $width1;
  ul { list-style-type: none; }
}
 
#neko{
  width: $width1;//こっちでも使える
}

[ローカススコープの例]

1
2
3
4
5
6
7
8
9
10
#navbar {
  $width1 : 5em;  //ここに書くとローカルスコープ、このブロック内部でしか使えなくなる。
  width: $width1;
  height: $width1;
  ul { list-style-type: none; }
}
 
#neko{
  width: $width1;//これはエラーになる。
}

グローバルとローカルスコープに同名の変数は使用することができない。

1
2
3
4
5
6
7
8
9
10
11
$width1 : 5em;
#navbar {
  $width1 : 3em;
  width: $width1;
  height: $width1;
  ul { list-style-type: none; }
}
 
#neko{
    width: $width1;
}

↓こう書いた場合、結果は次の様になる。

1
2
3
4
5
6
7
8
#navbar {
  width: 3em;
  height: 3em; }
#navbar ul {
  list-style-type: none; }
 
#neko {
  width: 3em; }

3.関数入門

関数を定義するには、@mixinを使用する。

1
2
3
4
5
6
7
@mixin hoge($huga) {
     #neko{
         width: $huga;
     }
 }
呼び出すには、@includeで呼び出す。
@include hoge(20px);

結果は下記

1
2
#neko {
  width: 20px; }

変数はいくつでも渡すことができる。
例:ListとNumber型のデータを渡した場合。

1
2
3
4
5
6
7
@mixin hoge2($foo,$bar) {
      #neko{
          padding: $foo;
          width: $bar;
      }
  }
  @include hoge2(20px 10px 0px 0 , 200px);

結果は下記

1
2
3
#neko {
  padding: 20px 10px 0px 0;
  width: 200px; }

変数をセレクタや文字列内に流しこみをしたい場合には、rubyの#{}
が使用できる。

1
2
3
4
5
6
@mixin hoge3($foo) {
     #neko #{$foo}{
       padding: 10px;
     }
 }
 @include hoge3(".neko");

結果は下記

1
2
#neko .neko {
  padding: 10px; }

引数なし関数

1
2
3
4
5
6
7
8
9
10
11
12
@mixin large-text {
    font: {
      family: Arial;
      size: 20px;
      weight: bold;
    }
    color: #ff0000;
  }
 
  h1{
    @include large-text;
  }

結果は下記

1
2
3
4
5
h1 {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000; }

4.制御文(繰り返し構文は使い道がありそう)

1
2
3
4
5
6
7
@for $i from 1 through 3 {
    .item-#{$i} { width: 2em * $i; }
  }
 
  @each $animal in puma, sea-slug, egret, salamander {
    .#{$animal}-icon {background-image: url('/images/#{$animal}.png');}
  }

↓これは便利!

1
2
3
4
5
6
7
8
.item-1 {  width: 2em; }
.item-2 {  width: 4em; }
.item-3 {  width: 6em; }
 
.puma-icon       {  background-image: url("/images/puma.png"); }
.sea-slug-icon   {  background-image: url("/images/sea-slug.png"); }
.egret-icon      {  background-image: url("/images/egret.png"); }
.salamander-icon {  background-image: url("/images/salamander.png"); }