C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

CSS pre-processor; sass vs. less vs. styl

つい先日、 CleverCSS-hs はそのCSSプリプロセッサ−としての思想はクレバーで良いものだ、と紹介しました。しかし、最後にHakylから使うモジュールとして組み込むに当たっては unsafePerformIO の目的外使用というアレゲな事に。あれのソースコードは…失礼ながらクレバーとは思えない。また、現状で私が使うには次の様な問題がある事にも気づいた:

  • CSS3 の HSLA() などに対応しておらず、これが妙に展開されてしまう
  • list-style-type など複数のハイフネーションにより結合されたエレメントの分解が1段階分しか機能しない( list -> style -> type はヘンテコリンにコンパイルされてしまう)

なぜ、 String -> String ではなく IO (Either String String) で根深く IO でラップする様な実装にしてしまっているか…という点も疑問だし、実装もごちゃごちゃしていてあまり美しいコードには見えない…。 CleverCSS コマンドという1つの完成品としてはなかなか良いと感じただけに、ちょっと残念。

と、いうわけで、「作るか」の前に既存の一般的な CSS プリプロセッサについて確認しておくことにした。

偶然、つい最近に代表的な CSS プリプロセッサのうち3種類を比較した記事を書いてくれていた人が居たのでこれを読んでみる事にしよう。比較しているのは以下の3つ:

Johnathan Croom による Sass vs. LESS vs. Stylus

文法

Sass と LESS について、

Sass と LESS は何れも標準的なCSS文法を採用しているよ。つまり既存のCSSからの変換が楽なんだね。Sassは .scss 、 LESS は .less という拡張子を採用しているよ。

へー。私はそんなの求めてないからどうだっていいけど。(.css ==(1)==> .scss ==(2)==> .css の(1)とか人間が手作業でする必要ないですし、完全に Sass なり LESS なりを使う目的である美しくて楽なCSS生成コードに後腐れなくしちゃった方がその後の為だとも思うんですがどうなんでしょうネ。)

ちなみに、 Sass には旧式の文法があって、それを使うなら ; だとか { } だとかを省略できてしまうんだ。でもそれは旧式の仕様だから今から使うって人は使っちゃダメだぞ!

え、ちょっと何言ってるのか意味が…。いや、言ってる事は分かるし、記事を書いてる Johnathan の主張は正しい。ある仕様に於いて deprecated な旧式の後方互換性の為だけに残されている仕様を新たにユーザーが用いるなど混乱を来すだけだ。しかし、 ; とか { } は旧式の文法でなければ省略できないのか…、 Sass とか LESS というのは一体何を考えて作っているのか確認する必要がある。

冒頭に .sass について記述がある。

第二に、古い構文としてインデント構文(または単に "サス")てのがあります。 これは HAML の簡潔さにインスパイアされたもので、CSSにもその様な簡潔さを求める人達を対象としたものです。 ; や { } の代わりに、行のインデントを用います。こちらの構文は旧式という事にはしますが、サポートし続けられます。インデント構文での拡張子は .sass を使います。

どうやら deprecated では無いらしい。非推奨ではなく、Sassというフレームワークに措いてはサポートは続けるけれど新式の文法を作ったから新しい改良とかはそっちでやるからね、とかそういうニュアンスに思える。実際、公式サイトでは .scss のどこがどう嬉しいのか知れない CSS に対する記述のアドバンテージの薄いコード例の他、 .sass による簡潔でより美しく私には見えるコード例も併記されている。

.sass を使う事を前提に、 Sass は悪くない選択肢だと思われる。しかし、 .sass を旧式として .scss を新たに開発するなど、どうも私には開発者なりユーザーなりの意図が理解できない…。その点で Sass は今ひとつ使いたくない。あとなんかよく見たら gem install sass とか書いてるし。

次に、 Less とやらも公式サイトを確認してみよう。・・・ブラケットだらけで今ひとつ・・・。ただ、どうやらこれは JavaScript であるらしく、 npm install less とあるから Node.js のモジュールとして簡単に使えるであろう点は嬉しい。

私にはクライアントサイドのJavaScriptCSSに変数やネストを書いたソレを動的にJSによりあたかも有効なCSSが適用されたかの様にDOMへ適用するという行動は理解に苦しむが…。WEBはコンパイルされるべきである。

ここで気づいた。なるほど Sass というのは Ruby が動的にCSSを生成するのにも使えるし、事前に静的にそれを評価してCSSを生成して置く事もでき、基本的にはその動的に生成する中で変数やネストなど使って少しはユーザーフレンドリーで便利にしたいという事が開発理由なのだろうか。また、 LESS に於いてはそれが JavaScript であり、 Node.js ないし、実行時にブラウザーにそれを評価させる事を目的としつつ、こちらも一応静的に生成する事もできるよ、と。

これはいくらプログラムのソースがクレバーでも私が求めるCSSプリプロセッサ−としてはクレバーさが足りないか、目的がなんか違う。

今回の比較で残っているのは Stylus というプリプロセッサーだけ。 Johnathan の記事に戻ってちょっと読んでみよう。

Stylus の構文はもっと冗長だよ。拡張子は .styl を採用していて、標準CSS文法は許容、なんだけど実はちょっと別の構文バリエーションも用意されていて、そっちだと全ての { } やら ; はオプションだよ。

冗長なら用はありま…んー…、なにそのオプション構文とか言うの、(私の目的に対しては)普通に良いんじゃない? .sass のインデントによるネストなどは無いらしいけど、 { } と ; を省略できるだけでもだいぶ可読性や編集性は向上する。…するが…、なんかこれもいまひとつ…。

やはり CleverCSS ルールでなおかつソースの実装もクレバーなものが欲しい…。ソースがクレバーとは例えばCSS3で新たに追加される事になっている HLSA への対応を最初から考慮しているか、あるいはさくっと文法やソースの構造的に追加したり、削除したりできるような美しい設計と実装のソースが…。あと haskell なら String -> String すればいいだけのライブラリなのに String -> String -> [(String String)] -> IO (Either String String) とかわけわかんない仕様にした挙句に根深いところまで IO でラップしてるとか;w;

・・・やはり・・・作るか・・・?