Sassの変数使用時に覚えておきたい6つのこと
コーダーのココエです。今回は前置きなしです、思いつかないからw
今回は、Sassの変数についてまとめました。
記事の対象者としては、Sassのインストールが完了していて、ちょろっと使ってみました!っていう方になります。何卒ご了承を。
目次
- 変数のスコープ
- 変数の名前解決
- 変数の名前解決(2)!defaultフラグ
- 変数の名前解決(3)変数定義されていない変数の呼び出し
- 変数の名前解決(4)構文ブロック内の変数宣言
- ショートハンドでmarginのプロパティ値を変数で指定する時の注意
変数のスコープ
まず、”スコープ”ってなんぞや?という方のために。
プログラミングでのスコープとは、ある変数や関数が特定の名前で参照される範囲のこと。ある範囲の外に置いた変数等は、通常、その名前だけでは参照できない。このときこれらの変数はスコープ外である、「見えない」といわれる。
参照元記事:Wikipedia
変数が参照される範囲のことですね。
Sassの変数は、Javascriptの変数のスコープと似ていて、グローバルスコープとローカルスコープが存在します。
グローバルスコープになる条件
スタイル定義ブロック(※1)の外側に定義した変数。
1 2 3 4 5 6 7 8 |
[sourcecode lang="css" highlight="2"] //Scss document $margin: 10px; //グローバルスコープ #section1 { margin: $margin; } [/sourcecode] |
ローカルスコープ
スタイル定義ブロック(※1)で定義されている。ネストされたセレクタのレベル範囲内がスコープとなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[sourcecode lang="css" highlight="5,9"] //Scss document $margin: 10px; //グローバルスコープ #section1 { $marginSec1: "20px"; //ローカルスコープ margin: $marginSec1; .subSec1 { $marginSubSec1: "5px"; //ローカルスコープ margin-top: $marginSec1; //上位のローカルスコープ padding: $marginSubSec1; } } [/sourcecode] |
※1:セレクタから始まるスタイル定義ブロックでなくても、ブロックで定義されている感じです。詳しくは「変数の名前解決(4)構文ブロック内の変数宣言」参照。
目次
変数の名前解決
ちなみに、”名前解決”ってなんぞや?という方のために。
名前と実体の関係を明らかにすること
参照元記事:Wikipedia
意外とここは重要だったりします。
Javascriptでは、以下のように関数(Sassに置き換えるとスタイル定義ブロック)内でグローバルで定義した変数名と同じ変数名を定義しても、(以下の文のケースだと)関数内だけで適用されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[sourcecode lang="javascript"] //Javascript document var test = "testだよ"; function func() { var test = "funcの中のtestだよ"; console.log(test); } func(); //console.log -> funcの中のtestだよ console.log(test); //console.log -> testだよ [/sourcecode] |
ですが、これと同じようなことをSassでやろうとすると、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[sourcecode lang="css" highlight="12"] //Scss document #section1 { $margin: 10px; margin: $margin; //10px .subSec1 { $margin: 20px; margin: $margin; //20px } .subSec2 { margin: $margin; //20px (10pxではありません) } } [/sourcecode] |
ファイル内に、同じ変数名が登場すると、その度に変数の値を上書きしていきます。
上記のソースの例では、.subSec1内でだけで使う意図で宣言した$marginが、上位の$marginの値を上書きしています。
上記のような短いソースコードでは、間違いに気づきやすいのですが、よく使われそうな変数名を使っていて、かつ長いコードのタッグができた場合にはまりやすいので、気を付けましょう。
変数の名前解決(2)!defaultフラグ
先ほど、Sassの変数の名前解決方法を説明しましたが、変数定義時に”!default”フラグをつけることで名前解決の動きが変わります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[sourcecode lang="css" highlight="9,10"] //Scss document $margin: 10px; #section1 { margin: $margin; //10px .subSec1 { $margin: 20px !default; margin: $margin; //10px (20pxではありません) } .subSec2 { margin: $margin; //10px } } [/sourcecode] |
上記の例では、.subSec1のmarginの値は、グローバル$marginで指定している10pxになります。
変数定義時に!defaultフラグを付けると、!defaultフラグを付けた変数定義以前に、同じ変数名の変数定義があれば、その値を優先させる、という動きをします。
!defaultフラグの使用例は後述します。
変数の名前解決(3)変数定義されていない変数の呼び出し
!defaultフラグの使用例の解説の前に、スコープの範囲内にない変数、または変数定義されていない変数を呼び出ししようとするとどうなるかの説明します。
まあ、もちろんエラーが発生します。
1 2 3 4 5 6 7 |
[sourcecode lang="css"] //Scss document #section5 { color: $color; //Error } [/sourcecode] |
こんなケースあるの?なんでそうなるわけ?ダメなの見ればわかるじゃん。。。と思われるかもしれませんが、以下のようなファイル構成の場合は、これやりがちです。
1 2 3 4 5 6 7 8 9 10 |
[sourcecode lang="css" highlight="7"] //Scss document of "id5.scss" @import "id5_style"; #section5 { background: $bgColor; //#ccc color: $color; //Error } [/sourcecode] |
1 2 3 4 5 6 7 |
[sourcecode lang="css" highlight="4"] //Scss document of "_id5_style.scss" $id : 5; //$color: #000; $bgColor: #ccc; [/sourcecode] |
※イメージとしては、IDごとにファイルが作成されていくパターン。
- 「id5.scss」に、ID5のスタイルの定義セットモジュール「_id5_style.scss」をimport。
- ID5の#section5は、デフォルトの文字色を利用したいから、_id5_style.scssの$color定義を削除する。(line4)
- $colorの変数が定義されていないためエラー。(line7)
みたいな流れですね。
!defaultの使用例
ここで!defaultフラグの登場です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[sourcecode lang="css" highlight="5,6"] //Scss document of "id5.scss" @import "id5_style"; $bgColor: #ff0000 !default; $color : #aaa !default; #section5 { background: $bgColor; //#ccc color: $color; //#aaa } [/sourcecode] |
1 2 3 4 5 6 7 |
[sourcecode lang="css"] //Scss document of "_id5_style.scss" $id : 5; //$color: #000; $bgColor: #ccc; [/sourcecode] |
「id5.scss」$bgColor, $colorに!defaultフラグをつけて変数定義しました。
このようにすると、「変数定義されている」&「!defaultフラグの変数定義前の変数値が適用される」で、エラーになることなく、意図したスタイルが適用されます。
変数の名前解決(4)構文ブロック内の変数宣言
Sassには制御構文などの構文がいくつかあります。(@if, @for, @each, @whileなど。)
この構文の中で変数定義した場合のスコープ。どうなるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[sourcecode lang="css"] //Scss document $test : true; @if $test == true { $test2 : #ccc; } #section6 { color: $test2; } [/sourcecode] |
一見、エラーなく通りそうなコードですが、これエラーがでます。(Undefined variable: “$test2″って言われる。)
どうやら変数のスコープは、セレクタから始まるスタイル定義ブロック、というわけではないようで、ブロック単位でみているようです。
このケースの解決方法は、やはり!defaultフラグを使うのがよいでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[sourcecode lang="css" highlight="3"] //Scss document $test2 : #000 !default; $test : true; @if $test == true { $test2 : #ccc; } #section6 { color: $test2; } [/sourcecode] |
ショートハンドでmarginのプロパティ値を変数で指定する時の注意
最後。CSSプロパティでショートハンドが使えるもの。かつ、値が数値(px)&ネガティブの時の注意です。
1 2 3 4 5 6 7 8 |
[sourcecode lang="css"] //Scss document $margin: 5px; #section { margin: $margin -$margin $margin; //0px 5px (5px -5px 5pxではない) } [/sourcecode] |
上記の例、結構やりがちです。
なんで、0px 5pxというコンパイル結果になってしまったか。答えは、$margin -$marginのところで演算されてしまっているから。
これを回避するには、かっこを使います
1 2 3 4 5 6 7 8 |
[sourcecode lang="css" highlight="5"] //Scss document $margin: 5px; #section { margin: $margin (-$margin) $margin; //5px -5px 5px } [/sourcecode] |
ネガティブマージンを使うときは、とにかくかっこで括る癖をつけた方がよいです。
という感じですが、いかがでしたでしょうか?
次回はCompassの便利なヘルパについて書こうと思います。
ではでは。
参考サイト:Sass公式サイト・変数の章