読者です 読者をやめる 読者になる 読者になる

世の中のCSSプリプロセッサーがどれもクソだから自作したった

タイトルは釣りです。Stylusは最高だと思うし、Sassはいつも使っています。Lessは…うん、いい感じだと思います。

Yet Another CSS Preprocessor

YACP(Yet Another CSS Preprocessor)という、CSSプリプロセッサーを作った。名前は考えるのめんどうだったので適当に付けた。作ったと言っても、前回のブログを書いたときに作ったrework-rule-bindingを使ってreworkでビルドしただけ。

インストールはnpmから。

$ npm install -g yacp

autoprefixerを組み込んでいるので、ベンダープレフィックスを気にしなくていい。SassみたいにCompassのCSS3のmixinを@includeする必要もない。

他にはrework-varsも使っていて、W3Cの変数定義の構文が使える。

/* input.css */
:root {
  var-font-lg: 18px;
}

.btn-lg {
  box-shadow: 5px 5px;
  font-size: var(font-lg);
  padding: 5px 10px;
}

コンパイルは、

$ yacp < input.css > output.css

で、こうなる。

/* output.css */
.btn {
  /* ベンダープレフィックスの付与 */
  -webkit-box-shadow: 10px 10px;
  box-shadow: 10px 10px;
  /* 変数の展開 */
  font-size: 18px;
  padding: 5px 10px;
}

でも1番の特徴というか他のCSSプリプロセッサーとの差別化としては、rework-rule-bindingで特定のルールセットのカスケーディングを禁止できることだ。rework-rule-bindingにより、丸かっこ「()」で囲んだセレクタと「%」から始まるセレクタが持つルールセットはカスケードしない。

またYACPでは、「%」から始まるセレクタのみ継承対象であり、このセレクタはSassのプレースホルダセレクタと同様に出力されない。

%att {
  color: red;
  font-weight: normal;
}

.attBox {
  /* %attを継承 */
  extends: %att;
  padding: 15px;
}

こんな感じで使う。継承するときの構文は、extend:, extends:, inherit:, inherits:が使える。

CSSプリプロセッサ

前回の記事にも書いたけど、現状のCSSプリプロセッサーはCSSに便利なシンタックスシュガーを定義したものに過ぎず、DRYを加速させることはできるが本質的にCSSの設計を良くするものではない。

しかし、CSSプリプロセッサーは必要だと思う。いや、CSSプリプロセッサーが必要というよりも、SassやStylusにある"@extend"を使った、他のルールセットを継承する機能が必要なのである。

他のルールセットを継承することにより、意味のレベルでルールセットを分けることができる。これにより、ついにオブジェクト指向CSSを真に実現することができる。CSSプリプロセッサーの必要性についてはこの記事に書かれており、大いに賛成している。

しかしSassやStylusでは、継承元のルールセットもカスケーディングにより上書きされていく。

/* Sass(.scss) */
.att {
  color: red;
  font-weight: normal;
}
.attBox {
  @extend .att;
  padding: 15px;
}
.att {
  font-size: 14px;
}

Sassでこのように書くと結果は以下のようになる。

/* 出力 */
.att, .attBox {
  color: red;
  font-weight: normal;
}
.attBox {
  padding: 15px;
}
.att, .attBox {
  font-size: 14px;
}

このように継承元となるルールセット(.att)はカスケーディングし、継承先で予期せぬ結果になる場合がある。またSassやStylusでは、プレースホルダセレクタ以外のルールセットも継承することができるので、安易に@extendし、膨れ上がったCSSファイルを幾度と見てきた。

その点YACPでは、プレースホルダセレクタだけしか継承できないので下手な使い方をしてCSSファイルが大きくなることもない。しかもその継承元はカスケーディングされないという保証がある。

CSSの在り方

CSSはどうあるべきなのだろうと考える。CSSはもともと文書に簡単なレイアウトと装飾を施すための言語だった。しかしCSS3には、柔軟なレイアウトや複雑な装飾を施すための多くのプロパティが追加された。またこれからも増え続けていくであろう、デバイス幅の異なる未知の端末に1ソースで対応する、レスポンシブWebデザインという思想がある。これらの理由から、近年のCSSの記述は複雑化してきている。

CSSは、ただWebのビジュアルデザインを表現できれば良いというものではない。Webサイトのパフォーマンスの観点からもそうだし、CSSも他のプログラミング言語と同様に保守の対象であるべきである。

ここまで書いたことは当たり前のことかもしれないが、現状CSSはかなり適当に書かれ、杜撰な管理がされていることは少なくない。その理由はCSSの記述が柔軟すぎることにもあるが、そもそもCSSを書く人はほとんどがデザイナー上がりの人で、思った通りのビジュアルが表現できればいいと考えているからではないか。また、プログラマはビジュアルが絡む分野を避ける傾向がある気もする。その点@tjholowaychukとかはすごいなあと思ってる。いやはやー、日本で僕ぐらい頭使ってCSS書いてる人ってどのくらいいるのかなあと思う。

ああ、ついつい偉そうなことを言ってしまった。これもまあ、セルフブランディングということで。 自分にプレッシャーをかけて精進していきたい。