SASS
- CSSを効率的に書く為の機能
- .sass(Ruby/Haml系)
- .scss(CSS)→CSSらしく記述でき、デザイナでも修正できるので主流となっている
⇒さらに詳しく
- HTMLによるマークアップを簡略化するためのHamlから派生。
- コンパイラーはRubyで実装。
- SCSS(.scss)ファイルのCSSファイルへの変換。
- サーバーサイドでの利用を想定。
- 非常に豊富な機能を持っており、条件分岐や繰り返しによる柔軟な制御が可能。
- 日本語のドキュメントが多く、開発コミュニティが安定。
- Compassフレームワークが使えて便利?
前提知識
- HTML/CSS/CSS3
- Unix Command
公式サイト/学習サイト
- Sass: Syntactically Awesome Style Sheets
- ドットインストール(Sass/SCSS入門 (全15回))
- CSSコーディングで泣かないためのSassの基礎知識と10の利点 (1/3)
- CSSコーディングで泣かないためのSassの基礎知識と10の利点 (2/3)
- CSSコーディングで泣かないためのSassの基礎知識と10の利点 (3/3)
- SassでCSSの弱点を克服しよう
SASS & SCSS のメリット
- 変数が使える。
- CSSの継承をネストでまとめられる。
- ネームスペースでネストできる。
- Partial(@importでCSSファイルを1つにまとめられる。)
- @mixinと@includeでスタイルを使い回せる。@mixinでは引数も使える。
- 算術演算子で値の加減乗除ができる。
- 別の単位同士で演算できる。
- 条件分岐(@if)や繰り返し(@for, @while, @each)処理ができる。
- コンパイルオプションで変換の仕方を変えられる。
変換の流れ
- SCSSをCSSに変換し、「css」フォルダに保存する。
- cssに保管されたCSSをindex.htmlでインポートする。
フォルダ構成
+-index.html
+-scss(記述ファイル保存先)
+-main.scss
+-css(変換後ファイル保存先)
+-main.css
+-main.css.map
セレクタに変数を代入
style.scss
@h1-color:red;
@h2-color: darken(@h1-color, 10%);
@h1-size: 24px;
@h2-size: @h1-size - 8px;
@header: h;
@color : color;
@dir : "/img";
@{header}1{
font-size: @h1-size;
@{color}: @h1-color;
}
@{header}2 {
font-size: @h2-size;
@{color}: @h2-color;
background: url("@{dir}/bg.png");
}
style.css
h1 {
font-size: 24px;
color: red;
}
h2 {
font-size: 16px;
color: #cc0000;
background: url("/img/bg.png");
}
ネスト/疑似クラス(&)
style.scss
header {
font-size: 18px;
a {
color: red;
&:hover {
color: green;
}
}
}
// .button-ok, .button-ng
.button {
&-ok {
color: green;
}
&-ng {
color: red;
}
}
style.css
header {
font-size: 18px;
}
header a {
color: red;
}
header a:hover {
color: green;
}
.button-ok {
color: green;
}
.button-ng {
color: red;
}
簡単な変換例
sample.sass
body
color: #000
sample.scss(CSSに近い)
body{
color:#000;
}
↓ コンパイル
sample.css(CSSに近い)
body {
color:#000;
}
SCSS記法とSASS記法とCSSの違い
SCSS記法 | SASS記法 | CSS | |
---|---|---|---|
波括弧 {} | 必要 | 不要 インデントで ネスト |
必要 |
セミコロン(;) | 必要 | 不要 | 必要 |
コロン(:)の後にスペース | 不要 | 必要 | 不要 |
ミックスイン | @mixin | = | なし |
インクルード | @include | + | なし |
拡張子 | .scss | .sass | .css |
環境(インストール)
console
# Ruby インストール状態の確認(インストール済)
$ ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin13]
$ sudo gem update --system
$ sudo gem install sass
Fetching: sass-3.4.18.gem (100%)
Successfully installed sass-3.4.18
Parsing documentation for sass-3.4.18
Installing ri documentation for sass-3.4.18
Done installing documentation for sass after 6 seconds
1 gem installed
$ sudo gem list sass
*** LOCAL GEMS ***
sass (3.4.18)
SCSS ⇒ CSS 変換
main.scss(変換元ファイル)
/**
* 変換後、反映されるコメント
*/
// 変換後、反映されないコメント
# main { /*親要素*/
width : 90%; /*属性*/
p { /*子要素*/
font-size:16px;
a {
text-decoration: none;
/*&=入れ子の構造でhoverが有る場合の親要素を指す。*/
&:hover {
font-weight: bold;
}
}
}
}
console
# sass (オリジナル):(出力先)
$ sass scss/main.scss:css/main.css
# 字下げが綺麗になる。
$ sass --style expanded scss/main.scss:css/main.css
- nested/expanded/compact/compressedのオプションを使用可。
main.css(変換先ファイル)
@charset "UTF-8";
/**
* 変換後、反映されるコメント
*/
# main {
/*親要素*/
width: 90%;
/*属性*/
}
# main p {
/*子要素*/
font-size: 16px;
}
# main p a {
text-decoration: none;
/*&=入れ子の構造でhoverが有る場合の親要素を指す。*/
}
# main p a:hover {
font-weight: bold;
}
/*# sourceMappingURL=main.css.map */
SCSSに変更がある場合、自動的に変換する。
console
$ sass --style expanded --watch scss:css
>>> Sass is watching for changes. Press Ctrl-C to stop.
[Listen warning]:
Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback.
>>> Change detected to: scss/main.scss
write css/main.css
write css/main.css.map
# Ctrl+Cで終了
変数の使用
- 変数は「$変数名:値;」で定義する。
main.scss
/**
* 変数:データにつけるラベル
* データ型(数値、文字列、真偽、色、リスト)
* 四則演算も可能
*/
$baseFontSize: 14px;
# main {
width : 90%;
p {
font-size:$baseFontSize;
.sub {
font-size: $baseFontSize - 2px;
}
}
}
main.css
@charset "UTF-8";
/**
* 変数:データにつけるラベル
* データ型(数値、文字列、真偽、色、リスト)
* 四則演算(+ - * /) も可能
*/
# main {
width: 90%;
}
# main p {
font-size: 14px;
}
# main p .sub {
font-size: 12px;
}
/*# sourceMappingURL=main.css.map */
変数の埋込み
- 変数の埋込みは「**$FOO+$BAR」で連結する。もしくは「#{$FOO}#{$**BAR}」のように埋込む。
- 「#{$FOO$BAR}」とコーディングしたところ、$FOOと$BARの間に半角スペースが開いたため、この記述は不可?
main.scss
/**
* 文字列変数を埋込む
*/
$imageDir: "../img/";
$image: "bg.png";
# main {
width : 90%;
p {
font-size:#{12 + 12}px;
//background: url($imageDir + "bg.png");
background: url("#{$imageDir}#{$image}");
}
}
main.css
@charset "UTF-8";
/**
* 文字列変数を埋込む
*/
# main {
width: 90%;
}
# main p {
font-size: 24px;
background: url("../img/bg.png");
}
/*# sourceMappingURL=main.css.map */
色を扱う(Sass Built-in Functions)
main.scss
/**
* 色を埋込む
*/
$brandColor: red;
// $brandColor: #ff0000;
// $brandColor: rgb(255, 0, 0, 0.9);
# main {
width : 90%;
p {
font-size:14px;
// lighten, darken
color: lighten($brandColor, 30%);
}
}
分岐(@if, @else)
main.scss
$debugMode: true;
$x: 30;
# main {
@if $debugMode == true { // == , != , <=, >=
color: red;
} @else {
color:green;
}
p {
@if $x > 20 { color: red; }
}
}
main.css
# main {
color: red;
}
# main p {
color: red;
}
/*# sourceMappingURL=main.css.map */
ループ(@for, @while)
main.scss
@for $i from 10 through 14 {
.fs#{$i} { font-size: #{$i}px; }
}
$i: 10;
@while $i <= 14 {
.ws#{$i} { font-size: #{$i}px; }
$i: $i + 1;
}
main.css
.fs10 {
font-size: 10px;
}
.fs11 {
font-size: 11px;
}
.fs12 {
font-size: 12px;
}
.fs13 {
font-size: 13px;
}
.fs14 {
font-size: 14px;
}
.ws10 {
font-size: 10px;
}
.ws11 {
font-size: 11px;
}
.ws12 {
font-size: 12px;
}
.ws13 {
font-size: 13px;
}
.ws14 {
font-size: 14px;
}
/*# sourceMappingURL=main.css.map */
リスト
main.scss
$animals: cat, dog, tiger;
@each $animal in $animals {
.#{$animal}-icon {background: url("#{$animal}.png");}
}
@each $animal in cat, dog, tiger {
.#{$animal}-icon {background: url("#{$animal}.png");}
}
main.css
.cat-icon {
background: url("cat.png");
}
.dog-icon {
background: url("dog.png");
}
.tiger-icon {
background: url("tiger.png");
}
.cat-icon {
background: url("cat.png");
}
.dog-icon {
background: url("dog.png");
}
.tiger-icon {
background: url("tiger.png");
}
/*# sourceMappingURL=main.css.map */
関数(@function)・デバッグ表示(@debug)
関数内の変数はプライベード変数となっている事に注意する。
main.css
$totalWidth: 940px;
$columCount: 5;
@function getColumnWidth($width, $count) {
$padding: 10px;
$columnWidth: floor(($width - ($padding * ($count - 1))) / $count);
@debug $columnWidth;
@return $columnWidth;
}
.grid {
float: left;
width: getColumnWidth($totalWidth, $columCount);
}
main.css
.grid {
float: left;
width: 180px;
}
/*# sourceMappingURL=main.css.map */
ファイル分割(Partial)
_settings.scss
$totalWidth: 940px;
$columCount: 5;
_functions.scss
@function getColumnWidth($width, $count) {
$padding: 10px;
$columnWidth: floor(($width - ($padding * ($count - 1))) / $count);
@debug $columnWidth;
@return $columnWidth;
}
main.scss
@import "settings";
@import "functions";
.grid {
float: left;
width: getColumnWidth($totalWidth, $columCount);
}
@mixin & @includex
main.scss
@mixin round ($radius) {
border-radius: $radius;
}
.label {
font-size: 12px;
@include round(5px);
}
main.css
.label {
font-size: 12px;
border-radius: 5px;
}
/*# sourceMappingURL=main.css.map */
継承(@extend)
main.scss
// @extend(継承)
// .errorMsg, .warningMsg
.msg {
font-size: 12px;
font-weight : bold;
padding: 2px 4px;
color: white;
}
.errorMsg {
@extend .msg;
background: red;
}
.warningMsg {
@extend .msg;
background: orange;
}
main.css
.msg, .errorMsg, .warningMsg {
font-size: 12px;
font-weight: bold;
padding: 2px 4px;
color: white;
}
.errorMsg {
background: red;
}
.warningMsg {
background: orange;
}
/*# sourceMappingURL=main.css.map */