近年、フロントエンドのコーディング周りで、CSSメタ言語(CSSプリプロセッサ)を利用するケースが増えています。
今まであまり触る機会がなかったのですが、私も流れに乗って新しめのCSSメタ言語「Stylus」についての概要と主要機能をまとめてみました。
少し長いですが、おつきあい下さい!
目次
1.そもそもCSSメタ言語って?2.Stylusとは
3.Stylusの書き方
4.Stylusでできること
ネスト(入れ子)
親要素参照
変数
継承(extend)
ミックスイン
パーシャル
演算
条件分岐と繰り返し
5.まとめ
そもそもCSSメタ言語って?
CSSメタ言語は、CSSの生産性向上の為に拡張された技術です。普通のCSSと異なり、セレクタを入れ子にする、四則演算、変数、関数、ifやeachなどの条件分岐ができることが特徴です。CSSに慣れていないプログラマにも受け入れやすい技術だと思います。
CSSメタ言語には今回説明する「Stylus」の他にも「Sass」「Less」等があります。
各ルールに従い、Stylusなら拡張子「.styl」、Sassなら拡張子「.scss」(又は「.sass」)でスタイルを指定し、そのファイルを通常のCSSにコンパイル(変換)して使用します。
Stylusとは
StylusはSassとLessのいいとこどりと言われているCSSメタ言語の一つです。Sassほどは機能は多くはありませんが、シンプルな記述方法で気軽にCSSが書けて、柔軟性が高いことが特徴です。
node.jsのexpressやjadeと同じ人が開発しています。導入にはnode.jsなどのインストールが必要ですが、インストール関係は今回は割愛します。他に紹介して下さってる方がいるのでそちらをご参照下さい。
※Sublime TextやCodeには対応していますが、Dreamweaverには非対応です。
コンパイルは、タスクランナーの「Gulp」や「Grunt」を使うと、他のタスクとともに自動化させることができて便利だし効率的です。
gulp.js – the streaming build system Grunt: The JavaScript Task Runner Gulpを使ってBrowser Sync + Sass, Less or Stylus + Coffee Scriptなタスクを作る
Stylusの書き方
基本の書き方
従来のCSS形式でも記述可能ですが、「:(コロン)」、「;(セミコロン)」、「,(カンマ)」、「{ }(波括弧)」が省略可能です。記号を省略することで記述量が減り、シンプルな形式で記述することできるので、スピードアップにも繋がります。
.stly(Stylus形式)
.hoge
width 100px //記号の省略が可能
.hoge2 {
width: 100px; //従来通りの描き方でもOK
}
.css(コンパイル後)
.hoge {
width: 100px;
}
.hoge2 {
width: 100px;
}
コメントの書き方
コンパイル時に残る記述方法と残らない記述方法があります。.stly(Stylus形式)
// インラインコメント(コンパイル時になくなる)
/*
通常のコメント(コンパイル時に残る)
*/
.css(コンパイル後)
/*
通常のコメント(コンパイル時に残る)
*/
複数クラス指定
カンマ区切り又は改行することで、一度に複数のセレクタをプロパティとして定義することができます。.stly(Stylus形式)
//カンマ(,)区切り
textarea, input
border 1px solid #eee
// 又は改行
textarea
input
border 1px solid #eee
.css(コンパイル後)
textarea,
input {
border: 1px solid #eee;
}
Stylusでできること
ネスト(入れ子)
インデントを入れることで、入れ子にすることができます。同じクラスを繰り返し使うストレスが軽減されますし、記述量が減りメンテナンス性が向上します。
ただ、入れ子のしすぎは可読性の低下、セレクタが長くなることでのパフォーマンスの低下(若干ですが)が懸念されますので、程々にしておくことをオススメします。
.stly(Stylus形式)
body
color #f00
p
color #000
.css(コンパイル後)
body {
color: #f00;
}
body p {
color: #000;
}
親要素参照
「&」を使うことで、親のスタイルやセレクタを参照することができます。.stly(Stylus形式)
// 擬似クラスで使われることが多いです
a
input
color #a7a7a7
text-decoration underline
&:hover
color #000
tect-decoration none
// カラーなどのパターンがある場合にも
.footer
background-color #fff
&.typeA
background-color #000
&.typeB
background-color #333
.css(コンパイル後)
a,
input {
color: #a7a7a7;
text-decoration: underline;
}
a:hover,
input:hover {
color: #000;
tect-decoration: none;
}
.footer {
background-color: #fff;
}
.footer.typeA {
background-color: #000;
}
.footer.typeB {
background-color: #333;
}
変数
変数を割り当てることができます。あらかじめ好きな名前(変数名)を決めて、「=」で繋いで値(スタイル)を代入しておけば、スタイルシートのどこででも変数名で値を呼び出して指定することができます。
変数名で使える文字は英数字と「_(アンダースコア)」「-(ハイフン)」です。
.stly(Stylus形式)
font-size = 14px
red = #dc143c
body
font font-size Arial, sans-serif
border 2px solid red
.css(コンパイル後)
body {
font: 14px Arial, sans-serif;
border: 2px solid #dc143c;
}
継承(extend)
他のセレクタに指定したスタイルを、好きなセレクタへ適用することができます。使いたいセレクタのクラスを、「@extend」で指定してスタイルを呼び出して継承します。
コンパイルすると、定義スタイルを読み込んだセレクタと「,(カンマ)」区切りでグループ化されます。
.stly(Stylus形式)
.btn
color #000
background-color #fff
border solid 1px #666
width 80px
// 呼び出し
.btn-A
@extend .btn
width 200px
.btn-B
@extend .btn
width 150px
.css(コンパイル後)
.btn,
.btn-A,
.btn-B {
color: #000;
background-color: #fff;
border: solid 1px #666;
width: 80px;
}
.btn-A {
width: 200px;
}
.btn-B {
width: 150px;
}
複数のクラスを呼び出したい場合は、「@extends」とし、クラス名を「,」で区切って一行で記述できます。また、「$」を先頭に付けるとコンパイル時に出力されません。 単体で使わなければ$を付ける方が、CSSサイズを小さくできます。
.stly(Stylus形式)
.box-base
background-color #ccc
.header
.box-base
background-color #fff
$box-special // $を付けるとコンパイル時に出力されない
background-color #000
.box-border
border none
// 呼び出し
.box-A
width 100px
@extend .box-base
.box-B
width 200px
@extend .header .box-base
.box-C
width 300px
@extends $box-special, .box-border
.css(コンパイル後)
.box-base,
.box-A {
background-color: #ccc;
}
.header .box-base,
.box-B {
background-color: #fff;
}
.box-C {
background-color: #000;
}
.box-border,
.box-C {
border: none;
}
.box-A {
width: 100px;
}
.box-B {
width: 200px;
}
.box-C {
width: 300px;
}
ミックスイン
こちらも定義したスタイルを呼び出すという点では、継承(extend)と同じですが、セレクタのグループ化はされません。また、ミックスインでは引数を使うことができるのが大きな特徴で、定義したスタイルの値の一部を変更することができます。
.stly(Stylus形式)
// スタイル定義
border-radius(n = 2px) {
-webkit-border-radius: n;
border-radius: n;
}
// スタイル呼び出し
div {
border-radius();
}
p {
border-radius(4px);
}
a {
border-radius: 4px;
}
.css(コンパイル後)
div {
-webkit-border-radius: 2px;
border-radius: 2px;
}
p {
-webkit-border-radius: 4px;
border-radius: 4px;
}
a {
-webkit-border-radius: 4px;
border-radius: 4px;
}
また、ミックスインの機能を使ってベンダープレフィックスを定義しておけるので便利です。.stly(Stylus形式)
vendor(prop, args)
-webkit-{prop} args
-moz-{prop} args
{prop} args
.hoge
vendor('box-shadow', 1px 0 0 #CCC)
.css(コンパイル後)
.hoge {
-webkit-box-shadow: 1px 0 0 #ccc;
-moz-box-shadow: 1px 0 0 #ccc;
box-shadow: 1px 0 0 #ccc;
}
パーシャル
CSSにコンパイルする必要が無いファイルは、ファイル名の前に「_(アンダースコア)」を付与することで、コンパイル後にCSSファイルが生成されません。これをパーシャルファイルと呼びます。CSSを役割や機能で複数ファイルに分割し、@importで読み込むことがあると思いますが、Webサイトの読み込みが遅くなってしまう問題もあります。
読み込み速度を考えればCSSは1ファイルにまとめたいところですが、それでは管理が大変なことになります。
そこでパーシャル機能を使って、分割で作成したStylusファイルを、1つのCSSにまとめることができます。スタイルの修正は分割したパーシャルファイルで行うので、メンテナンス性も問題ありません。
読み込みたいファイルに、@importでファイルを指定すれば読み込むことができます。この際、「_(アンダースコア)」と拡張子は省略することができます。
.stly(Stylus形式)
@import "reset";
@import "parts";
@import "font";
@import "mixin";
パーシャルファイルを読み込んだStylusファイルをコンパイルすると、読み込んだファイルで定義した全スタイルがCSSとして1ファイルにコンパイルされます。便利な機能ですが、「IE9以前で1つのCSSファイル、又は1つのstyleタグ内のセレクタは4095個目までしか適応されない」「IE9以前でCSSファイル、またはstyleタグは31個目までしか適応されない」という制限がありますので、ご注意下さい。
演算
様々な計算や文字列の操作も可能です。変数よりもプログラム色が強くなってきました。どの機能まで使うかは各プロジェクトの決めだと思います。
計算と真偽値
.stly(Stylus形式)
body
foo 5px + 10
foo 2 ** 8
foo 5px * 2
foo !!''
foo hoge and fuga and pugya
foo hoge or fuga or pugya
foo 1..5
foo 1...5
foo 'hoge' is a 'string'
foo (1 2 3) == (1 2 3)
foo (1 2 3) == (1 2)
foo ((one 1) (two 2)) == ((one 1) (two 2))
foo ((one 1) (two 2)) == ((one 1) (two))
foo ((one 1) (two 2))[0]
foo 3 in (1 2 3 4)
.css(コンパイル後)
body {
foo: 15px;
foo: 256;
foo: 10px;
foo: false;
foo: baz;
foo: foo;
foo: 1 2 3 4 5;
foo: 1 2 3 4;
foo: true;
foo: true;
foo: false;
foo: true;
foo: false;
foo: one 1;
foo: true;
}
値や文字列の操作
.stly(Stylus形式)
body
foo: foo + bar
foo: 'foo ' + bar
foo: 'foo ' + 'bar'
foo: 'foo ' + 5px
foo: 2s - 500ms
foo: 5000ms == 5s
foo: 50deg
.css(コンパイル後)
body {
foo: foobar;
foo: "foo bar";
foo: "foo bar";
foo: "foo 5px";
foo: 1.5s;
foo: true;
foo: 50deg;
}
色の操作
.stly(Stylus形式)
body
foo: white - 50%
foo: black + 50%
foo: #eee - #f00
foo: #eee - rgba(black,.5)
foo: #cc0000 + 30deg
.css(コンパイル後)
body {
foo: #808080;
foo: #808080;
foo: #0ee;
foo: rgba(238,238,238,0.5);
foo: #c60;
}
文字列置換
.stly(Stylus形式)
body
foo: '%s / %s' % (5px 10px)
.css(コンパイル後)
body {
foo: 5px / 10px;
foo: MS:WeirdStuff(opacity=1);
foo: MS:WeirdStuff(opacity=1);
}
条件分岐と繰り返し
forループやif文などを用いた条件分岐をプログラミング言語に近い感じで行うことができます。HTMLやCSS中心にやってきた方は、この辺で悩む方が出てくると思います。(私もです。慣れれば便利だと思います。)
1行目が 配列の定義。,(カンマ)区切ることもできます。また、 変数の展開は{}で行えます。
if/else文
if文を使って、特定の条件を元に、その後の処理を行うかどうかを決めます。条件・状況に応じて異なるスタイルを指定することができます。.stly(Stylus形式)
liquid = true
.hoge
if liquid
width 100%
else
width 960px
.css(コンパイル後)
.hoge {
width: 100%;
}
for/in文
forを使うことで、指定した開始数値から終了数値まで1つずつ増やしながら繰り返しの処理を行うことできます。.stly(Stylus形式)
array = 1 2 3 4
for num in array
.mg-{num * 5}
margin num * 5px
.css(コンパイル後)
.mg-5 {
margin: 5px;
}
.mg-10 {
margin: 10px;
}
.mg-15 {
margin: 15px;
}
.mg-20 {
margin: 20px;
}
まとめ
これだけやっていれば必ず素敵なCSSになるという訳ではありませんが、高機能だし上手に使えばCSS作成の効率化&スピードアップ、メンテナンス性の向上が大きく期待できます。何より同じ記述を繰り返さなくて済むのが大きいと思います。プロジェクトやチーム状況を見て、選択肢の一つとして検討してみて良い技術だと思います。
(勿論、こういったCSSメタ言語を使わないというのもひとつの判断です。)
技術的には、特にCSSに慣れていないプログラマやエンジニアの方にはなじみやすい印象ですが、HTMLやCSSメインでやってきたコーダーや、プログラミング嫌悪病の方には多少ハードルが高く感じられると思います。
チームメンバーがStylusの機能や使い方をきちんと理解していないと破綻してしまったり、せっかくの機能が使いこなせない恐れがあります。
SassやLessなどを経験されていない方は入りやすいと思いますが、文献や情報が少ないので経験ない方はハマった時に苦労されるかも知れません。その際は、Sass・Lessで調べてみると解決策が見つかることがありますので試してみて下さい。
情報は公式サイトを中心にネットで集めることになるかと思います。
公式サイト
公式サイトを日本語に訳してくれた方がいます
「Stylusが目指すCSSプリプロセッサ」(考え方が参考になります)
多少の懸念点はありますが、シンプルな記述方法や魅力的な機能も多くあるStylusです。まずはいろいろ触ってみて下さい!