Enduring CSSの設計思想 第1回 ECSSが目指す設計

CSS設計方法、Enduring CSS(ECSS)は、複雑さを排除し、ある程度のCSS容量増加を覚悟することで、CSSの寿命を伸ばすというアプローチを取っています。今回は、その基本となっている考え方から解説します。

発行

著者 高津戸 壮 テクニカルディレクター
Enduring CSSの設計思想 シリーズの記事一覧

はじめに

CodeGridでは過去に、OOCSS、SMACSS、BEMの3つのCSS設計概念を紹介しました。

この連載で紹介するEnduring CSS(以降、ECSS)は、これら3つと同じように、CSSの設計方法を示したものです。エンジニアのBen Frain氏が電子書籍として著し、現在はWebサイト上でもすべてのコンテンツが読めるようになっています。

先に挙げた3つのCSS設計概念と比較すると、本記事執筆時の2016年5月現在、ECSSの知名度は圧倒的に低いです。しかしながら、筆者はこの本に書かれている内容が、非常に実践的で役に立つものであると感じました。この連載では、ECSSはどういうものかというのを簡単に解説します。本連載では、便宜上、CSS設計概念としてのECSSを「ECSS」、書籍自体を「ECSS本」と呼ぶことにします。

なお、本連載は、OOCSS、SMACSS、BEMの概要を理解していたほうがより深く理解できるものと思います。これら3つのCSS設計概念については、上記連載をご参照ください。

ECSSが実現させたいこと

WebサイトのCSSをいかに長生きさせるか。これはCSSを書く者にとっては永遠のテーマであり、どのようにしても達成されないことはわかってはいるものの、なんとかそこに近づこうと日々奮闘しているのが現実ではないでしょうか。OOCSSを考えたNicolle Sullivanも、「CSS is too fragile(CSSはとても壊れやすい)」と、自身のプレゼンテーションの中で述べていました。なぜ壊れやすいのかというのは、先に挙げた過去の連載で触れているので、ここでは割愛します。

先に挙げた3つのCSS設計概念はそれぞれ、この問題を解決するためのアプローチの一種です。ECSS本の著者Ben Frain氏は、OOCSS、SMACSS、BEMそれぞれを実際に試したものの、それだけでは問題を解決できなかったのでECSSを考えたと書いています。

ECSSの始めの頭文字、Enduringは、「長続きする、永続的な、不朽の、我慢強い、辛抱強い」という意味を持っています(参考: アルク)。では、ECSSはどうやってそれを実現するというのでしょうか。ECSSには、OOCSS/SMACSS/BEMで語られていない、WebサイトのCSSを長生きさせるためのヒントがあります。それがどんなものなのか、見ていきましょう。

OOCSSのCSS設計

ECSSは、結果的にOOCSSと逆のアプローチになったと著者は書いています。まずは、OOCSSがどんなものだったのかを、ざっとおさらいしてみます。

OOCSSのコアとなる考えは、オブジェクト指向の継承になぞらえた「ベース」と「スキン」を使ってモジュール(UIを構成する単位)を作り、この集まりでページを構成するというものです。同種のモジュールは、その共通部分となるスタイルを「ベース」としてまとめ、バリエーションごとの差分を「スキン」として別に定義します。このようにベースとスキンを組み合わせることで、モジュールのバリエーションを効率的に表現します。このように抽象化を行うことで、同じスタイルの組み合わせは何度もCSSの中に登場しなくなり、結果としてCSSの容量を減らすことが出来ます。

親ボタンと共通するスタイルを「ベース」としてまとめ、各子ボタンのバリエーションを「スキン」として定義している

Nicolle Sullivanは、OOCSSを説明する際に、Webサイトはレゴの組み合わせであると表現しました(Object Oriented CSS)。綿密に設計されたレゴによりWebサイトを設計すれば、最高のパフォーマンスを出せるということは、壊れやすいCSS問題に立ち向かう、一つの有効な手法であることに間違いありません。

減った容量の代わりに足されるもの

多くのCSS設計に悩む実装者達と同じく、筆者もOOCSSは非常に良い考えであると思い、実制作に活かしてきました。Webサイトはモジュールの組み合わせで考え、そのモジュール群には一貫したデザインルールがあるべきであると。そう、たとえばボタンのバリエーションにはルールを持たせ、無駄のないCSS設計は、無駄のないデザインがあってはじめて実現するものであると、説教じみた話をしたこともしばしばあります。

しかし、現実的にそれが完璧に行えるかというと、なかなか難しいものがあります。OOCSSでは、先に述べた「ベース」と「スキン」を体現するクラスを一つの要素に同時に指定することでモジュールを作っていきます。この、複数のクラスを用いレイアウトを抽象化するという考えは、結果としてCSSの容量を減らすことができますが、代わりにCSSに足すものがあります。それは複雑さです。

OOCSSで組まれたサイトにおいて、何か一つのUIの実装を見てみれば、それは複数のモジュールの組み合わせによって成り立っているかもしれません。そして、それぞれのモジュールにはスキンが適用されているかもしれません。そのような複雑な構造を、簡単に理解することができるのかと言われたら、素直に首を縦に振れないのではないでしょうか。

仮に、高いスキルを持つ実装者が複数いたとして、設計概念の意思疎通が完璧に行えていたとしても、その複雑さを共有するのには時間とドキュメンテーションが必要です。OOCSSを突き進めれば、自然とビジュアルデザインのルールを整えることも必要不可欠となるはずです。OOCSSは、統一されたデザイン性と、ミニマムなCSSをもたらすでしょうが、最高に整備されたOOCSSのコードは、最高に複雑になっているかもしれません。

CSS設計に求めるもの

さて、これが自分の欲しかったものか?と言われるとどうでしょう。1kbや2kbのCSS容量の差が、トラフィックのコストに重大なインパクトを与える、ページビューのものすごい多いWebサイトであったならば、OOCSSのアプローチは最適かもしれません。しかし、筆者には、そのように高いパフォーマンス性を求められた機会は一度もありませんでした。これは、多くの人にとって同様ではないでしょうか。

ここまでで書いたことはOOCSSを突き詰めた場合の話でして、実際にはそこまで無駄を減らしてどうこうするということは稀かとは思います。しかし、兎にも角にも、OOCSSでベース、スキンと組んでいけば、複雑になっていくことはひとつ、間違いありません。

OOCSSが広く知られてからしばらくして、SassなどのCSSプリプロセッサが広く使われるようになりました。Sassのextendは、OOCSSがやりたかったモジュールの継承をスマートに実現してくれてしまう夢のような機能でありますが、CSSに(正確にはその前段階のsassファイルに)複雑さをもたらすという点においてはまったく同じです。mixinにもそのような側面があると言えます。

CSSをうまく書けば書こうとするほど、複雑さがコードに混ざっていってしまうように思えるわけですが、これは仕方のないことなのでしょうか。スケールし続けるサイトに対応するには、全体を完全に把握し続けるために時間をかけ、ドキュメンテーションを完全に行い、意思疎通を完璧に行うという道しかないのでしょうか。

ECSSはちょっと違う考え方をします。複雑さを排除し、ある程度のCSS容量増加を覚悟することで、CSSの寿命を伸ばすというアプローチを取ります。

ECSSの「分けて考える」という思想

何度かECSS本を読み、ECSSの考え方でもっとも重要なのは「分けて考える」というところであると、筆者は理解しました。ECSSは、ちゃんと分離されてさえいれば、分離された領域を超えてスタイルが干渉したりすることはなく、また、書いたCSSを捨ててしまうことが簡単になると考えます。

たとえば、ECサイトのHTML/CSSを書くとします。AmazonのようなWebサイトを想像してください。このECサイトは、以下の4つのテンプレートで構成されているとします。

  • トップページ
  • カテゴリトップ(例: 家電、インテリア、キッチン用品……)
  • 商品詳細
  • ショッピングカート

このようなサイトを作るとき、筆者は、/assetsなどにサイト全体で共通のCSS、JS、画像を置き、すべてのテンプレートにまたがって共通利用できるようなUIをモジュールとして切り出せないか考え、モジュール一覧ページやスタイルガイドをまずは作成。一通りのモジュールを作った上で、具体的なテンプレートを完成させるという方法で実装を行っていました。サイト全体を一つのまとまりであると考える設計です。

ECSSは、そのような考え方をしません。この例であれば、たとえば上記4テンプレートをそれぞれまったく別のものとして考えるところから始めます。まったく別というのはどういうことかというと、CSS、JS、画像らのセット(以降、便宜上「アセット」と呼ぶことにします)を、完全に分けて考えるということです。たとえば、先の/assetsの内容は、以下のようなディレクトリ構成になるかもしれません。

/assets
    /TopPage
        /css
        /imgs
        /js
    /CategoryTop
        /css
        /imgs
        /js
    /ProductDetail
        /css
        /imgs
        /js
    /ShoppingCart
        /css
        /imgs
        /js

各々のディレクトリに、各テンプレートで必要なアセットを置きます。トップページで使うモジュールのアセットはすべてTopPageディレクトリへ、カテゴリトップで使うモジュールのアセットはすべてCategoryTopへ……という具合に、完全に分けてしまいます。この例では、テンプレートごとに完全に別物として扱うという想定で解説していますが、この分け方は自由に決めてかまいません。このあたりは次回解説していきます。

実際にこのようなディレクトリ構造にして、それぞれのページで必要なものだけを読み込ませるのか。もしくは、ビルドを前提として最終的には一つのCSS、JSにまとめるのかというところについては重要ではありません。重要なのは、全体で一つとして扱うのではなく、分けて管理するというところです。

このように、完全に分けて管理することで、運用を楽にすることができるとECSSは考えます。たとえばトップページをリニューアルしたいと思ったら、TopPageディレクトリを丸ごと捨て、TopPageV2などというディレクトリを作り、そこに新しいアセットを置きます。TopPageディレクトリには、トップページで使うものしか置かないと決めているのです。だから、トップページを新しくするのであれば、TopPageディレクトリの中にある、もう使わなくなるアセットは、気兼ねなく消すことができます。

これが、以下のように分けられていなかったらどうでしょう。

/assets
    /css
    /imgs
    /js

トップページで使われている部分をCSSの中から、大量の画像の中から探し出し、これは消して良いものだろうかとビクビクしながら消すか、もしくは諦めて残したままにするかのどちらかになってしまいがちではないでしょうか。

この、「分けて考える」というのが一つ、ECSSを理解する上で重要なポイントのように思います。いや、言ってみれば、「分けられてさえいればどうにでもなる」と理解したほうがいいかもしれません。

ここまでのまとめ

今回は、ECSSの考え方でもっとも重要な「分けて考える」ということについてOOCSSと比較して解説しました。

しかし、分けて考えるとは言っても、複数のCSSを読みこんだり、ビルドして一つのCSSにするなどしてしまえば、どこか別のところで書かれたCSSが余計な悪さをし、意図しないスタイルがあたってしまったりすることは当然ありえます。また、先ほど挙げた例では、テンプレートごとに分けるというアプローチを取っていますが、そうは言っても共通のパーツなどがあるだろうと疑問を抱いている読者もいるのではないでしょうか。

次回は、実際にECSSで書かれたECSSのWebサイトを紐解きつつ、より詳しく「分けて考える」方法について解説していきます。