恐竜に教える現代のCSS – Part 2

CSSプリプロセッサで新構文を使う

以上、CSSを使った基本的なスタイル指定とレイアウトを取り上げました。次に、CSS自体を言語として扱いやすくするために作られたツールについて説明します。まずはCSSプリプロセッサです。

CSSプリプロセッサを使うと、別の言語で記述したスタイルをブラウザが解釈できるCSSに変換する、ということが可能になります。これは昔、ブラウザへの新機能の実装が遅々として進まなかった頃は重要事項でした。最初のメジャーなCSSプリプロセッサはSassで、2006年にリリースされました。新しい簡潔な構文(括弧に代わるインデント、セミコロンを使わないなど)と、変数、ヘルパー関数、演算など、CSSには欠けていた高度な追加機能が特徴です。変数を伴うSaasを使って先の事例のカラーセクションを記述すると、次のようになります。

  1. $dark-color: #4a4a4a
  2. $light-color: #f9f9f9
  3. $side-color: #eee
  4. body
  5. color: $dark-color
  6.  
  7. header, footer
  8. background-color: $dark-color
  9. color: $light-color
  10.  
  11. main
  12. background: $light-color
  13. nav, aside
  14. background: $side-color

再利用可能な変数を$記号で定義し、括弧とセミコロンが除去されたことで見た目のスッキリした構文が作られているのが分かるでしょう。Sassの簡潔化された構文自体も確かに優れています。しかし当時は変数などの機能が革新的でした。簡潔でメンテナンスしやすいCSSの記述という新しい可能性を開いたからです。

Sassを使うには、Rubyをインストールする必要があります。通常のCSSにSassコードをコンパイルするのに用いるプログラミング言語です。次にSass gemをインストールし、コマンドラインでコマンドを実行し.sassファイルを.cssファイルに変換します。以下がコマンドの一例です。

  1. sass --watch index.sass index.css

このコマンドはindex.sassの名称のファイルに書かれたSassコードを、index.cssファイル内に通常のCSSとして変換します。(入力変更が保存されるたびに引数--watchが変換を実行させるので、便利です。)

この処理はビルドステップと呼ばれ、2006年当時はきわめて重大な導入の障壁でした。Rubyなどのプログラミング言語に慣れている人にはその処理は非常に容易です。しかし当時のフロントエンド開発者の多くはHTMLとCSSのみで構築をしており、そのようなツールを必要としなかったのです。そのため、CSSプリプロセッサが提供する機能を使いこなせるようエコシステムの全貌を把握するのは大きな負担でした。

2009年、Less CSSプリプロセッサがリリースされました。これもまたRubyベースであり、Sassとよく似た機能を備えていました。大きな違いは構文で、可能な限りCSSに近くなるよう設計されています。つまり、あらゆるCSSコードはLessコードとしても有効になるという意味です。同じ例をLess構文で記述したのが下記です。

  1. @dark-color: #4a4a4a;
  2. @light-color: #f9f9f9;
  3. @side-color: #eee;
  4. body {
  5. color: @dark-color;
  6. }
  7.  
  8. header, footer {
  9. background-color: @dark-color;
  10. color: @light-color;
  11. }
  12.  
  13. main {
  14. background: @light-color;
  15. }
  16. nav, aside {
  17. background: @side-color;
  18. }

ほとんど同じに見えますが(変数に$ではなく@プレフィックスを使うなど)、CSSと同じく波括弧、セミコロンが使われており、Sassの例ほどはすっきりしていません。しかし、CSSに似ていることで開発者にとってはより使いやすくなりました。2012年にLessは、コンパイルにRubyではなくJavaScript(厳密にはNode.js)を使うようになりました。この書き換えにより、LessはRubyベースの類似品よりも高速になり、ワークフローの中で既にNode.jsを使っていた開発者の支持を集めやすくなったのです。

このコードを通常のCSSに変換するには、まずNode.jsをインストール、次にLessをインストールしてから、以下のようなコマンドを実行してください。

  1. lessc index.less index.css

このコマンドはindex.lessの名称のファイルに書かれたLessコードを、index.cssファイル内に通常のCSSとして変換します。lesscコマンドには、(sassコマンドと異なり)ファイルの更新を監視する役割はないことに注意してください。つまり、自動的に監視、コンパイルを行うには別のツールをインストールする必要が出てきます。.lessファイルを使うと、処理がやや複雑になります。繰り返しになりますが、コマンドラインツールを使い慣れたプログラマであれば難はないのですが、ただCSSプリプロセッサを使いたいだけの人にはこれは高い障壁です。

Lessが評価を得るにつれ、Sass開発者たちは2010年、SCSSと呼ばれる新たな構文(Lessに似たCSSのスーパーセットでした)を追加して変化に対応しました。また彼らは、Ruby SassエンジンのC/C++ポートであるLibSassをリリースし、Sassをさらに高速化しつつ、様々な言語で利用できるようにしました。

CSSプリプロセッサのもう1つの選択肢は、2010年に登場したStylusです。ベースはNode.jsで、SassやLessよりも簡潔な構文が大きな特徴です。CSSプリプロセッサの話題は、最も知られているこの3つ(Sass、LessとStylus)に関するものがほとんどでしょう。結局、機能の面でこれら3つは全て非常に似ているので、どれを選んでもまず失敗はありません。

しかし中には、CSSプリプロセッサの必要性は薄れてきているのではないかと主張する人もいます。ブラウザがついにCSSプリプロセッサの機能(変数と演算など)を実装し始めたからです。さらに、CSSポストプロセスと呼ばれる別のアプローチによっても、(全く抵抗なしに)CSSプリプロセッサが過去の遺物となる可能性もあります。次はそのアプローチについて見ていきましょう。

CSSポストプロセッサの変換機能を使う

CSSポストプロセッサはJavaScriptを使ってCSSを解析し、有効なCSSに変換します。感覚としてはCSSプリプロセッサによく似ています。同じ問題を解決する別の方法と考えてもよいでしょう。大きな違いは、CSSプリプロセッサが特殊な構文によって変換の必要な事項を特定するのに対し、CSSポストプロセッサは通常のCSSをパースし、特殊な構文を一切使わずに変換できることです。例を見るのが一番分かりやすいでしょう。上記で最初に定義したヘッダタグのスタイルの一部を見てみましょう。

  1. h1, h2, h3, h4, h5, h6 {
  2. -ms-hyphens: auto;
  3. -moz-hyphens: auto;
  4. -webkit-hyphens: auto;
  5. hyphens: auto;
  6. }

太字の項目をベンダープレフィックスと呼びます。ブラウザは、ベンダープレフィックスを利用して実験的に新規CSS機能を追加したりテストしたりし、実装が確定するまで開発者がそれらの新規CSS属性を使う手段を提供します。ここでは、-msプレフィックスはMicrosoft Internet Explorer用、-mozプレフィックスはMozilla Firefox用、-webkitプレフィックスはWebKitレンダリングエンジンを地用しているブラウザ(Google Chrome、Safari、Operaの最新バージョンなど)用です。

これらのCSS属性を使うために様々なベンダープレフィックスをいちいち入れるのはかなり面倒です。必要に応じて自動的にベンダープレフィックスを入れられるツールがあれば便利でしょう。CSSプリプロセッサでそのような類の動作は可能です。例えば、SCSSで次のようなことができます。

  1. @mixin hyphens($value) {
  2. -ms-hyphens: $value;
  3. -moz-hyphens: $value;
  4. -webkit-hyphens: $value;
  5. hyphens: $value;
  6. }
  7. h1, h2, h3, h4, h5, h6 {
  8. @include hyphens(auto);
  9. }

このように、Sassのmixin機能を使えば、CSSの塊を定義して別の場所で再利用できるのです。このファイルを通常のCSSにコンパイルする際には、@includeステートメントは全て、合致した@mixinにあるCSSで置き換えられます。総合的には悪くないソリューションですが、まずベンダープレフィックスを要するあらゆるCSS属性に各mixinを定義しなければなりません。また、これらのmixinの定義は保守を行う必要があります。ブラウザのCSS互換性アップデート等により不要になった特定のベンダープレフィックスを削除したりすることになります。

mixinを使う代わりに、一般的なCSSを書き、ツールで自動的にプレフィックスの必要な属性を特定して適宜追加するのも良い方法です。それがまさにCSSポストプロセッサにできることなのです。例えばPostCSSオートプレフィクサのプラグインを付けて使うと、ベンダープレフィックスなしで完全に通常のCSSを記述して、残りの仕事をポストプロセッサに任せることができます。

  1. h1, h2, h3, h4, h5, h6 {
  2. hyphens: auto;
  3. }

このコード上でCSSポストプロセッサを実行すると、hyphens: auto;の行が適当なベンダープレフィックスに置き換わります(オートプレフィクサの定義を参照するので、直接管理する必要はありません)。互換性や特殊な構文の心配をせずに通常のCSSを書けることになります。これは便利です。

PostCSSのオートプレフィクサ以外にも、仕事をラクにしてくれるプラグインがあります。cssnextプラグインがあれば、実験的なCSS機能を利用できます。CSSモジュールプラグインは、名称のコンフリクトを避けられるよう自動的にクラスを変えてくれます。stylelintプラグインはCSS上のエラーと一貫性のない規則を特定します。どのツールもこの2、3年に公開されたばかりで、以前は考えられなかった開発ワークフローを提案しています。

しかし、この進歩にも払うべきツケはあります。PostCSSのようなCSSポストプロセッサをインストールして使うのは、CSSプリプロセッサを利用するのと比べると手間がかかるのです。コマンドラインでツールをインストール、実行するだけでなく、それぞれのプラグインをインストール、設定し、より複雑な規則一式(どのブラウザを対象にするか、など)を定義していかなければなりません。コマンドライン1本でPostCSSを実行する代わりに、多くの開発者は設定変更の可能なビルドシステムにそれを統合しています。GruntGulpwebpackなどのビルドシステムは,
フロントエンドのワークフローで使う様々なビルドツールを管理するのに役立ちます。

注:全くの初心者の場合、モダンフロントエンドシステムの活用に欠かせない全てのパーツを把握するのは相当大変です。1から始めたい方は、私の記事[Modern JavaScript Explained For Dinosaurs(恐竜に教えるモダンJavaScript)](https://medium.com/the-node-js-collection/modern-javascript-explained-for-dinosaurs-f695e9747b70)も参考にしてください。フロントエンド開発者に役立つモダンな機能の活用に欠かせないJavaScriptツールを網羅しています。

CSSポストプロセッサをめぐっては議論があることも知っておくとよいでしょう。用語が紛らわしいという人もいます(全てCSSプリプロセッサと呼ぶべきでは?という議論や、単にCSSプロセッサと呼ぼうという意見など)。CSSポストプロセッサがあればCSSプリプロセッサの需要はなくなる、と考える人もいれば、両者を併用すべきという人もいます。いずれにしても、CSSの可能性の最先端を享受したいなら、CSSポストプロセッサの使い方を知って損はないはずです。


注釈:「ハハッ!CSSは勝手にどんどん変わり過ぎだと思うんだよ」
「まあ、いいとこ取りは無理だよ!」
「ハハッ!待って、どういうこと?」
「CSSが難しい、でも誰かがそれを改善するツールを作るのもイヤだ、って言ってるんだろ?」
「まあな!でもCSSを左右するのはツールだけじゃないぞ!」
「そこでCSS方法論が役立つかもしれないよ!」