CSSの構造化にSassを利用してみる(完)

2010年12月20日 加藤 雄亮 このエントリーをはてなブックマークに追加 Clip to Evernote

前回までは、Sassの基本構文や変数、演算子など、基本的な使用方法でした。
今回は、更に進んでCSSの構造化に不可欠な、外部ファイル読み込みや関数機能です。

ここから、JavaScript等のプログラミング知識が必要になってきます。
if文やfor文、while文などの制御構文も利用出来ます。更に関数と引数を組み合わせる事で、複雑なCSSが簡単に管理出来てしまいます。

前回までの内容

@ルール

SassではCSS3の@ルールを全てサポートしています。
また、Sassが拡張した@ルールも合わせて使用する事が出来ます。

@import

外部ファイルの読み込みをサポートします。
CSSの@import文として出力する事が出来ますが、それ以外に、SCSSやSassファイルをファイル内に読み込む事も可能です。

CSSの@import文として出力される場合
  • ファイル拡張子が.cssである場合
  • ファイル名が http:// で始まっている場合
  • ファイル名が url() で指定されている場合
  • メディアクエリが付加されている場合
上記以外は、指定されたファイル名の拡張子「.scss」か「.sass」を探し、ファイル内にマージします。

foo.scss
$width: 100px;

#foo {
    width: $width;
}


コンパイル前:style.scss
@import "foo.css";             // CSS出力有:拡張子が.css
@import "foo" screen;          // CSS出力有:メディアクエリ付加
@import "http://foo.com/bar";  // CSS出力有:http://で開始
@import url(foo);              // CSS出力有:url()で指定

@import "foo";                 // CSS出力無:内部に読み込み
// または、@import "foo.scss";
// 複数の場合:@import "foo", "bar";

#main {
    width: $width;
}



コンパイル後:style.css
@import url(foo.css);
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);
#foo {
    width: 100px; }

#main {
    width: 100px; }



また、Sassファイルの変更監視(–watchオプション指定)をしている場合は、外部SCSS, Sassファイルを保存する際、ファイル名の先頭にアンダースコア(_)を付けて不必要なCSSファイルへのコンパイルを防ぐ事が出来ます。

_foo.scss
$width: 100px;

#foo {
    width: $width;
}


コンパイル前:style.scss
@import "foo";

#main {
    width: $width;
}



コンパイル後:style.css
#foo {
    width: 100px; }

#main {
    width: 100px; }


※_foo.scssは「@import “foo”;」として読み込めますが、_foo.cssとしては出力されません。

@extend

他のセレクタのスタイルを継承する事が出来ます。

コンパイル前:style.scss
.error {
    border: 1px #f00;
    background-color: #fdd;
}
.seriousError {
    @extend .errer;
    border-width: 3px;
}



コンパイル後:style.css
.error, .seriousError {
    border: 1px #f00;
    background-color: #fdd; }

.seriousError {
    border-width: 3px; }




制御構文

Sassでは、3種類の構文をサポートしています。

@if

if文では条件を分岐して出力を変更出来ます。

コンパイル前:style.scss
$type: monster;

p {
    @if $type == ocean {
        color: blue;
    } @else if $type == matador {
        color: red;
    } @else if $type == monster {
        color: green;
    } @else {
        color: black;
    }
}



コンパイル後:style.css
p {
    color: green; }



@for

指定した回数分だけ処理を繰り返す事が出来ます。

コンパイル前:style.scss
@for $i from 1 through 3 {
    .item-#{$i} { width: 2em * $i; }
}



コンパイル後:style.css
.item-1 {
    width: 2em; }

.item-2 {
    width: 4em; }

.item-3 {
    width: 6em; }



@while

条件を満たす間、処理を繰り返す事が出来ます。

コンパイル前:style.scss
$i: 6;
@while $i > 0 {
    .item-#{$i} { width: 2em * $i; }
    $i: $i - 2;
}



コンパイル後:style.css
.item-6 {
    width: 12em; }

.item-4 {
    width: 8em; }

.item-2 {
    width: 4em; }




関数類似機能

一般的に言う「関数」そのものではありませんが、関数に類似した機能を使用する事が出来ます。
外部から引数を与え、内部の値を変更出来るので、構造化には必要な機能です。

@mixin, @include


関数定義:style.scss
@mixin large-text {
    font: {
        family: Arial;
        size: 20px;
        weight: bold;
    }
    color: #ff0000;
}



関数利用:style.scss
.page-title {
    @include large-text;
    padding: 4px;
    margin-top: 10px;
}



コンパイル後:style.css
.page-title {
    font-family: Arial;
    font-size: 20px;
    font-weight: bold;
    color: #ff0000;
    padding: 4px;
    margin-top: 10px; }



引数


コンパイル前:style.scss
@mixin custom-border($color, $width) {
    border: {
        color: $color;
        width: $width;
        style: dashed;
    }
}

p  { @include custom-border(blue, 1px); }
h1 { @include custom-border(red, 5px); }



コンパイル後:style.css
p {
    border-color: blue;
    border-width: 1px;
    border-style: dashed; }

h1 {
    border-color: red;
    border-width: 5px;
    border-style: dashed; }





現在では、JavaScriptで実装されているレイアウトや機能が、CSS3で実現出来つつある状況です。
今後は、CSSが複雑化していくのは目に見えているので、Sassが活躍する場が増えそうですね。