はじめに
これまで、CSSは素でstyle.css
のようなファイルにスタイルを書く方法が主流でした(私も最近までこちらでした)。
ですが、CSSだけで書いていると、どうも拡張性や保守性に欠けたりしてしまいます。
仕事だとあるあるだと思いますが、同じようなスタイルをひたすらコピペで違うクラスやIDを使っていたり、どうしても一部だけ違うデザインを適用させたくなってcolor: red;!important;
とか使って設計が崩壊していったりと、開発する上でCSSだけで書いているとルールを作るのも大変だし、チームで苦労することになります。
そこで、最近ではメタ言語と呼ばれる、CSSをよりプログラミングに近い形で書ける言語が出てきました。
これらのメタ言語とは、よりCSSを抽象的に書くことができて、プロセッサと呼ばれるものを使ってCSSを生成します。
つまり、もっと直感的にCSSを書けるってことですね!
かゆい所に手が届くというか、、そんな感じですw
CSSのメタ言語
有名なのは、
なんかがあります。
Sass(SCSS)
Sassが、括弧でSCSSと書いてあるのは、もともとSASS記法というので書かれていたんですが、Sass3.0からCSSちっくに書くことが出来るSCSS記法というのでも書けるようになったためです。
ようはどちらで書いても、同じCSSが生成されるので、自分に合った方を使えばいいと思います。
Sassの使い方
- rubyのインストール
Sassはrubyでコンパイルするのでとりあえずrubyが必要です。
私の環境(centOS)でインストールしたやり方をすべて残しておきます。
$ wget https://cache.ruby-lang.org/pub/ruby/2.2/ru
--2015-09-23 11:10:27-- https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz
cache.ruby-lang.org をDNSに問いあわせています... 103.245.222.68
cache.ruby-lang.org|103.245.222.68|:443 に接続しています... 接続しました。
エラー: 証明書に記載されている名前 `j.ssl.fastly.net` とホスト名 `cache.ruby-lang.org` が一致しません
cache.ruby-lang.org に安全の確認をしないで接続するには、`--no-check-certificate` を使ってください。
SSL による接続が確立できません。
' なんか怒られたので言われた通りに証明書チェックしないオプションをつける(自己責任で!)'
$ wget --no-check-certificate https://cache.ruby-l
--2015-09-23 11:10:38-- https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz
cache.ruby-lang.org をDNSに問いあわせています... 103.245.222.68
cache.ruby-lang.org|103.245.222.68|:443 に接続しています... 接続しました。
警告: 証明書に記載されている名前 `j.ssl.fastly.net` とホスト名 `cache.ruby-lang.org` が一致しません
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 16626772 (16M) [application/octet-stream]
`ruby-2.2.3.tar.gz` に保存中
100%[======================================================>] 16,626,772 13.3M/s 時間 1.2s
2015-09-23 11:10:40 (13.3 MB/s) - `ruby-2.2.3.tar.gz` へ保存完了 [16626772/16626772]
' 展開してインストール '
$ tar xvzf ruby-2.2.3.tar.gz
$ cd ruby-2.2.3
$ ./configure
$ make; make install
' 確認 '
$ ruby -v
- sassのインストール
rubyインストールしたのでgemで入れます。
$ gem install sass
$ sass -v
Sass 3.4.18 (Selective Steve)
準備おっけ。
sassの基本的な使い方
基本的な流れは、sassファイルを作成し、sassコマンドでcssを出力するだけです。
簡単なのでやってみます。
$red:#FF3399;
.red {
color: $red;
}
sass style.scss:style.css
すると、sassがstyle.css
ファイルを生成してくれます
.red {
color: #FF3399; }
/*# sourceMappingURL=style.css.map */
気付きましたか?
sassって変数使えるんですよ!!!
これすごくないですか?
例えば、こんな依頼があったとするじゃないですか。
上司: サイトの赤って今明るいじゃん?
私: はい。普通にCSSのred使ってるのでちょっと明るいかもしれませんね。
上司: 全部さ、`#FF3399`に変えてよ。
私: えっ・・はい。。(うわーred使ってる所を全部置換するのだりーーー)
上司: 不満か?
私: いえっ!すぐに取り掛かります!
〜〜〜〜 数日後 ~~~~~~
上司: おい!なんか問い合わせページのエラー文言だけ昔の赤色のままだぞ!
私: えっ・・(やべっここだけ別のスタイルシート使ってるの忘れてたー!)
これ、sass使ってれば、置換なんてする必要なくて、$red:red
を$red:#FF3399
にするだけで修正完了ですよ。
5秒ですよね。仕事爆速になりますよね!!
ちょっと話脱線しましたが、とにかく世界が変わるって事です。
ただ、このsassコマンド、色々便利なオプションがあるので紹介しておきますね。
sassの便利なオプション
--styleオプションで変換方法を変える
変換方法は主に4つ。
nested
, expanded
, compact
, compressed
これから、下のsassファイルをそれぞれのオプションで出力して結果の違いを見てみます。
$red:#FF3399;
.red {
color: $red;
&-.warning {
font-weight: bold;
}
}
-
- nested - sassファイルのネストの深さが引き継がれます
sass style.scss:style.css --style nested
出力結果
.red {
color: #FF3399; }
.red-.warning {
font-weight: bold; }
/*# sourceMappingURL=style.css.map */
-
- expanded - 典型的なCSSの記述スタイルにする
sass style.scss:style.css --style expanded
.red {
color: #FF3399;
}
.red-.warning {
font-weight: bold;
}
/*# sourceMappingURL=style.css.map */
-
- compact - セレクタと属性を1行で記述してくれます
sass style.scss:style.css --style compact
.red { color: #FF3399; }
.red-.warning { font-weight: bold; }
/*# sourceMappingURL=style.css.map */
-
- compressed - すごく圧縮してくれる方法。可読性は悪いが軽くなる
sass style.scss:style.css --style compressed
.red{color:#f39}.red-.warning{font-weight:bold}
/*# sourceMappingURL=style.css.map */
--watchオプションで自動コンパイルする
毎回ファイルを更新する度にコンパイルするのも面倒なので自動化しましょう。
sass --watch style:scss:style:css
こうしておくと、ファイルを更新すると下のように変更を検知して勝手にコンパイルしてくれます。
>>> Change detected to: style.scss
write style.css
write style.css.map
- ディレクトリ毎に指定
ちなみに、特定のディレクトリ配下をずっと監視することも可能です。
[ディレクトリ名]
の部分を.(ドット)
にしておけばカレントディレクトリを監視対象に出来ます。
sass --watch [ディレクトリ名]
- 他のオプションと併用
また、先ほどのstyleオプション等他のオプションと一緒に指定することも可能です。
sass --watch . --style compact
- フォルダ毎指定
普通は、sassディレクトリとcssディレクトリを作って、sassフォルダで作ったファイルをcssディレクトリに出力したいでしょう。
それも可能です。
sass --watch sass:css
- 出力ファイル名
sassコマンドで、対象のscssファイルと出力するcssのファイル名を指定しなければ、自動的にscssのファイル名で出力されます。
hoge.scssファイルを作るとこんな感じで、hoge.css
が出力されます。
>>> New template detected: hoge.scss
write ./hoge.css
write ./hoge.css.map
Sass記法とSCSS記法の違い
すいません。これまでずっとCSCCで書いてしまっていたんですが、ここで一旦SASS記法も紹介しておきます。
ちなみに、そんなに変わらないですが、私はCSSっぽく書けるSCSS記法の方が気に入ってます。
- SASSとSCSS記法の違い
(わかりやすくするためにCSSも書いておきます)
- | SCSS記法 | SASS記法 | CSS |
---|---|---|---|
波括弧{} | 必要 | 不要(半角スペーサー2個のインデントでブロックを表します) | 必要 |
セミコロン; | 必要 | 不要 | 必要 |
コロン:のあとのスペース | 不要 | 必要 | 不要 |
ミックスイン | @mixin | = | ☓ |
インクルード | @include | + | ☓ |
拡張子 | .scss | .sass | .css |
じゃあちょっと、ここで同じCSSをSASS記法とSCSS記法で書くとそれぞれどう変わるかを見てみましょう。
- SASS記法
$orange:orange
$red:red
= btn($radius, $bg_color)
border-radius: $radius
background: $bg_color
.red
color: $red
.btn-warning
+btn("3px", $orange)
.btn-error
+btn("3px", $red)
- SCSS記法
$orange:orange;
$red:red;
@mixin btn($radius, $bg_color) {
border-radius:$radius;
background:$bg_color;
}
.red {
color:$red;
}
.btn-warning {
@include btn(3px,$orange);
}
.btn-error {
@include btn(3px, $red);
}
- 出力されるcss
.red {
color: red; }
.btn-warning {
border-radius: "3px";
background: orange; }
.btn-error {
border-radius: "3px";
background: red; }
どちらも同じCSSが吐き出されているのがわかります。
個人的には、癖で波括弧書いたり、セミコロンを書いたりしちゃうので、SCSS記法の方が好きです。
さぁ、では基礎がわかった所でいよいよSASSのすごい所を色々と見ていきましょう。
Sassの最強機能7選
1. 変数
これはもう何度も出てますが、Sassでは変数が使えます。
$red: red;
$blue: blue;
.red {
color: $red;
}
.blue {
color: $blue;
}
便利ですよね。
2. ネストが使える
さて、今までCSSでは、div#main
直下のaタグのimgタグに対して指定するときは、#main > a > img
のようにセレクタを指定してました。
これ面倒なのは、#main
とa
とimg
それぞれにスタイルを当てたい時とか、セレクタをを合計で4つ書かないといけなかったんですよね。
Sassを使えばこんな面倒な書き方はしなくて良いのです。
#main {
width: 200px;
height: 100px;
& a {
& img {
width: 50px;
height: 50px;
}
}
}
#main {
width: 200px;
height: 100px; }
#main a img {
width: 50px;
height: 50px; }
3. 名前空間でネストが可能
同一の名前空間を持つプロパティの場合、この名前空間でネストが可能です。
.title {
font: {
family: family;
size: 1.5em;
color: blue;
}
border: {
radius: 4px;
color: red;
}
}
.title {
font-family: family;
font-size: 1.5em;
font-color: blue;
border-radius: 4px;
border-color: red; }
素晴らしすぎる・・・
4. @importを使って別のファイルを読み込める
importはCSSでも使えました。
ただし、それをやるには、style.css
、main.css
を2つ作って、style.css
でmain.css
をimport。とかやる必要がありました。
これはパフォーマンス的な観点であまりよろしくありません。
というのも、HTTPのリクエストはstyle.cssとmain.cssの2つ分のリクエストが走りますので、リクエストが多くなればなるほど負荷高騰につながりやすいのです。
じゃあSassだと何がいいの?っていうと、Sassの場合は別のSassファイルをimportすることになりますので、いくらimportしてようが最終的に出力されるCSSファイルは1つになります。
つまり、どんだけimportしてようがHTTPのリクエストは1回で済みます。
(あまりimportしすぎればその分CSSのファイルが大きくなって負荷が上がってしまうと思いますが・・)
実際にやってみます。
body {
width: 100%;
}
@import "fuga.scss";
.title {
font: {
family: family;
size: 1.5em;
color: blue;
}
border: {
radius: 4px;
color: red;
}
}
body {
width: 100%; }
.title {
font-family: family;
font-size: 1.5em;
font-color: blue;
border-radius: 4px;
border-color: red; }
ちゃんと読みめてますね。
ちなみに、importは、下のようにも書くことが出来ます。
@import url("style.scss");
5. mixinを使ってスタイルの使い回しが可能
これ、個人的にかなりアツいです。
何がアツいって、まず共通で使うようなスタイルを色んな所で使えるという点。そして引数が渡せるのです!!!
やってみましょう。
@mixin circle($width:50px, $height:50px, $bg_color:white) {
width: $width;
height: $height;
background: $bg_color;
}
.box1 {
@include circle(100px, 100px, red);
}
.box2 {
/* 引数を指定しなければデフォルト値が適用される */
@include circle();
}
.box1 {
width: 100px;
height: 100px;
background: red; }
.box2 {
/* 引数を指定しなければデフォルト値が適用される */
width: 50px;
height: 50px;
background: white; }
6. 四則演算が・・・できる!!
やばくないっすか?
よく、ボックスを横並びにする時なんかに、「え〜と・・・3等分だから、1/3で・・33.3333%。4等分だから・・25%か」とかってやってたのが考える必要なくなるんです。
.div1, .div2, .div3 {
float: left;
width: (100%/3);
}
.box1, .box2, .box3, .box4 {
float: left;
width: (100%/4);
}
.div1, .div2, .div3 {
float: left;
width: 33.33333%; }
.box1, .box2, .box3, .box4 {
float: left;
width: 25%; }
便利すぎる・・・・!!!!
7. 制御構文が使える!!!!!
制御構文って言うと難しく聞こえますが、単純に条件分岐とか繰り返しですね。
ifとかforがcssで使えるって事です。
なんかforとかは使いみちがわかるんですが、ifを使う場面がよくわかってないです。
とりあえず、@if
, @for
, @each
, @while
の4つは紹介しておきます。
$type: top;
.main {
@if $type == top {
padding: 10px;
} @else if $type == fotter {
padding: 5px;
} @else {
padding: 15px;
}
}
.main {
padding: 10px; }
.media配下の.img-1
, .img-2
とかにそれぞれ連番の画像を背景にしたいときとか
.media {
@for $i from 1 through 3 {
.img-#{$i} {
background-image: url("/img-#{$i}.png");
}
}
}
.media .img-1 {
background-image: url("/img-1.png"); }
.media .img-2 {
background-image: url("/img-2.png"); }
.media .img-3 {
background-image: url("/img-3.png"); }
- each
eachは配列が使えて便利!!
.media {
$image_lists: bird, dog, cat;
@each $value in $image_lists {
.img-#{$value} {
background-image: url("/img-#{$value}.png");
}
}
}
.media .img-bird {
background-image: url("/img-bird.png"); }
.media .img-dog {
background-image: url("/img-dog.png"); }
.media .img-cat {
background-image: url("/img-cat.png"); }
- while
$i: 1;
@while $i < 5 {
.item-#{$i} { width: 2em * $i; }
$i: $i + 1;
}
.item-1 {
width: 2em; }
.item-2 {
width: 4em; }
.item-3 {
width: 6em; }
.item-4 {
width: 8em; }
まとめ
※ 9月24日現在、まだSass(SCSS)部分までしか書いてないです。明日までにはLESSの方も追記します。
また、時間が間に合えばもっとこれらのメタ言語を使って高速に開発が可能になるgulpとかについても書いてみます。