CSS界隈は今どうなっているのか、そこで素人な私が思ったこと

この雑な文章は、[dots girl Advent Calendar 2015](http://qiita.com/advent-calendar/2015/dots_girls) の4日目の記事です。

# 今 CSS に何が起きている？

## CSS のシンプルなルール

CSS は Web ページの装飾・レイアウトのための言語です。プログラミング言語と比べると、CSS は非常にシンプルなルールの元に成り立っています。

- プロパティと値の組み合わせで、HTML にスタイルを適用する
- 上から書いた順にスタイルが適用される
- 詳細度の高い順にスタイルが適用される

たったこれだけが、CSSのルールです。いわゆるカスケーディングってやつです。

## CSS は壊れやすい

しかし最近、至る所で「CSS の壊れやすさ」について触れられています。

- [壊れやすいCSS](http://www.slideshare.net/masahirokobayashi0522/css-45161029)
- [なんでCSSすぐ死んでしまうん](http://www.slideshare.net/hayatomizuno/css-41084761)
- [メンテナブルでありつづけるためのCSS設計](http://www.slideshare.net/hiloki/maintainable-css)
- [CSS設計の長い夢](http://pepabo.github.io/docs/frontend/standard/css-architecture/)

なぜ「CSS は壊れやすい」のか？それは、CSS を書けば書くほど、CSS 同士の壊し合戦が起こるからです。

- 下にいるやつが上にあるやつを上書きする
- 詳細度の高いやつが低いやつを上書きする
- 親に与えたスタイルが全部子に継承される

これをスコープ問題と(私が勝手に)呼んでいます。

さらに CSS を書く担当が複数人になると、自分の意図しない干渉が多く発生することになります。
何も考えず書き足していると、気付けば身に覚えのないスタイルが適用されていたり、自分が書いたスタイルが他の人のスタイルを書き換えてしまったりすることがあります。

# CSS の問題を解決するための手段や思想

Web が複雑化・肥大化していった結果、上記のような CSS の問題は深刻になり、皆が「CSS つらい」と言い始めるようになりました。
そして、その問題を解決するための手段や思想が、色々と出てきています。

今回は、従来からよく行われていた「ルールを作る」というアプローチと、最近よく聞こえ始めた「CSS を変換する」というアプローチに分類し、(まだ開発者が使えない、仕様策定段階のものも含めて) さらっと紹介していきます。

- ルールを作るというアプローチ
    - コーディングガイドライン
    - CSS設計
- CSS を変換するというアプローチ
    - AltCSS
    - PostCSS / cssnext
    - CSS in JS / CSS in Modules
    - Web Components / Polymer
    - Houdini

## ルールを作るというアプローチ

まず考えられるのは、壊れにくい CSS を書くように努力することです。
CSS のルールは非常にシンプルなので、そこにチーム・プロジェクトに合ったルールを付け加えて、壊し合戦が起こらないようにします。

### コーディング規約

コーディング規約は、チーム・プロジェクトで定める書き方のルールです。
ディレクトリ構造やクラスの命名規則を定めたり、プロパティの書き順や指定するセレクタの詳細度などに制限を与えたりします。

どのようなコーディング規約を定めれば良いのかについては、[Google HTML/CSS Style Guide](http://re-dzine.net/2012/05/google-htmlcss-style-guide/) あたりに譲ることとします。
あとは [メンテナブルCSS](https://www.cyberagent.co.jp/techinfo/techreport/report/id=7926) でしょうか。

### CSS設計

しかし単純なコーディングガイドラインだけでは、CSS がお互いに壊し合ってしまう状況を打破するのは、難しいかもしれません。

そこで、設計の概念を CSS に持ち込んだものがここ数年になって出てきました。
その多くは、CSS のスコープ問題を命名規則やクラスの設計によって解決しにいこうとしています。

- OOCSS
- SMACSS
- BEM
- MCSS
- FLOCSS

## CSS を変換するというアプローチ

コーディング規約やCSS設計を定める上では、そのチーム・プロジェクトに合ったルールを作り、運用し続けることが大切です。

しかし逆に言えば、どんなスタイルガイドも設計も、そのチーム・プロジェクトでしか通用しません。
CSS という言語が持つ、本質的な問題は解決できていません。

そこで、そもそも CSS を使わず、CSS の代わりになるものや、CSS を拡張したものを使ったり作ったりするという選択肢も出てきました。

### AltCSS

簡単に言うと、CSS の代わりになる言語です。CSS の代わりになる独自の言語を書いて、それを CSS に変換します。
Sass などは有名なので、もはや説明は要らないかもしれません。

- Sass / scss
- Less
- Stylus

AltCSS を使うと、例えば変数や関数など、プログラミングちっくな CSS を書くことができます。
最終的には CSS に変換されるので、あまり CSS のルールから大きく外れたことはできませんが、CSS の機能を大幅に拡張するものです。メンテナンスしやすい CSS を書くことが、とても楽になります。

※以降はあまり詳しくないため、間違いがあるかもしれません。途中まで書いていて、上記 CSS における問題とは別かなという感じもしています…。ツッコミ歓迎です！

### PostCSS / nextcss

これは先行実装されている CSS の機能を、サポートされていないブラウザでも使えるような CSS に変換するものです。

厳密には、PostCSS はポストプリセッサ(CSS を入力として何らかの処理を行った CSS を出力するもの)のことを指していて、実際に新しい CSS を古い CSS に変換するのは、PostCSS で実装された cssnext、というニュアンスっぽいです。

[CSSのプリプロセスとポストプロセス、そしてReworkとPostCSS](http://morishitter.hatenablog.com/entry/2014/12/07/000205) が分かりやすいと思います。

nextcss では、カスタムプロパティやカスタムメディアクエリ、カスタムセレクタなどの機能が使えたり、便利な関数が使えたりするそうです。

### CSS in JS / CSS Modules

スコープのない CSS を卒業し、CSS で書かずに JavaScript でスタイルを書くという考えです。

具体的には、JavaScript でインラインスタイルを追加(!)してしまいます。
React の作者が提案したもので、React のように HTML(JSX) も JavaScript の中に入ってしまう場合に、CSS も持ってこよう！という思想です。

色々あるらしく、[ReactとCSS](http://blog.sasaplus1.com/2015/05/11/01/) にいくつか紹介されています。

また、CSS in JS の一つに CSS Modules というものがあります。
これは、CSS に与えるクラス名をハッシュにしてしまうことで、擬似的なスコープを作ってくれるものです。前述の CSS 設計で厳密な命名規則を用いなくても、`.button-_23_aKvs-b8bW2Vg3fwHozO`のような形に変換してくれます。

### Web Components / Polymer

Web Components は、HTML/CSS/JavaScript を一つの小さな部品として分割可能にするWeb標準化技術です。
現在策定中の仕様もありますが、一部ブラウザには既に実装されており、Polymer というポリフィルライブラリもあります。

大きく以下の4つの仕様があります。

- HTMLImports: HTMLをlinkタグで簡単にロードできる
- Templates: templateタグにより、DOMベースでテンプレートを使用できる
- CustomElements: 新しいHTML要素を定義できる
- ShadowDOM: HTML要素をカプセル化することで、スコープ問題を解決できる

この中でも ShadowDOM は要となる仕様で、これによって CSS が他のスタイルと干渉しなくなり、独立した部品を作ることができます。
ただ、現状ではベンダによって実装の方針が異なるなど、標準化に時間がかかっているようです。

### Houdini

Extensible Web (拡張可能なWeb) という考えから、CSS の低レベルな API を提供することで、開発者がCSS のポリフィル開発を簡単にできるようにしよう、という取り組みです。

まだ議論段階ではありますが、API が公開されれば皆が JavaScript を使って自由に CSS の機能を拡張できるようになるはずです。
Houdini により、CSS が見違えるような多機能な言語となっていく可能性もあると思います。

# 素人な私が思うこと

Web の使われ方はどんどん変わってきていて、CSS の担う範囲は年々増えてきています。
その中で、CSS も大きな変化を迫られているような気がします。

- 壊し合うことのない独立したスタイルを定義可能にする
- 皆が作った独立したスタイルを皆が使えるようにする

多様化していく Web に対して、ベンダが頑張るよりも開発者一人一人が開拓していくことで、より Web 自体がスピードアップしていくと良いなと思います。
そのためには、今こうして色んな手段や考え方で取り組まれている CSS のスコープ問題を、(できれば標準化された)統一された方法で解決されていくべきだな、とも。
共通の基盤の上で、皆が独立したスタイルを作って使うことができれば、CSS のエコシステム！ができる気がします。
それは JavaScript における JQuery と同じくらいのインパクトになるだろうと、今後期待しています。

以上、素人の見解でした！
明日は@Chitamaさんです。よろしくお願いいたします！