抽象化を避けるCSS設計方法論「Enduring CSS」 第4回

連載: Enduring CSS (4)

前回までで、Enduring CSS(以降ECSS)の考え方を紹介してきました。ECSSというのは端的に言うと「分けて考えよ」という設計思想です。当たり前ですけれども、どう「分けて」考えるかは、設計者自身に判断が任されています。

ECSSには、Webアプリケーション向けに考えられた設計方法であると書かれていますが、筆者Takazudoとしては、より広い範囲で応用できる考えだと感じました。今回は、どのようにECSSの考え方を活かすべきかという点について考えてみます。

コンポーネント指向のフレームワーク

2017年時点において、ReactやAngularのようなコンポーネントベースでWebアプリケーションを構築できるフレームワークが台頭しています。このようなフレームワークでは、コンポーネントの中にだけCSSを適用するアプローチを取ることができます。

例えばAngularでは、コンポーネントを定義するファイルの中で、以下のようにstyleUrlsにCSSファイルへのパスを指定することができます。

ここで指定されたCSSファイルの内容は、コンポーネントの内部にのみ適用されるよう、Angularが処理します。

この方法でアプリケーションを実装すれば、CSSの特徴である、書いたセレクタがグローバルに適用されてしまうという事態を避けることができるため、意図せず他の箇所にスタイルが適用されてしまうということがなくなります。

ECSSとこれらフレームワークには直接的な関わりはありませんが、このようなフレームワークが用意している、ローカルにのみCSSを効かせるという実装を利用することで、分離による保守性の向上というメリットを得ることができます。これは、ECSSの設計思想と非常に似た考えと言えます。ECSSはモジュールごとの分離を命名規則で実現し、これらフレームワークはその用意したフレームワークの機能の中で実現します。

このようなコンポーネント指向のフレームワークを用いてアプリケーションを設計する際、ECSSを理解することは、そのCSS設計のための助けとなるかもしれません。

制作チームが別れている運用体制

筆者Takazudoは、ECSSの考え方を、制作チームが別れている運用体制にて活かすことができたという話を聞きました。

私にその話を聞かせてくれた方は、一つのサイトを複数のチームで運用する際、どこまでを共通化して考えればよいのか、汎用的なモジュールをどう考えれば良いのかということについて悩んでいたようです。制作チームが別れていると、密に連携が取れるわけではないので、汎用的に作った細かいモジュールを、各チームで共有するのが難しいということでした。

その方は、そのような環境を改善するため、ECSSの考えを取り入れました。ヘッダとフッタのみを共通のモジュールとし、それ以外の箇所については、サイト上のカテゴリのまとまりごとに完全に分離してしまうことにしたそうです。具体的には、各々の管理範囲へ個別の名前空間を与え、CSSを書く際は、クラス名の頭にその名前空間の接頭辞をつけることをルールとし、そのクラスセレクタで基本的にCSSを書くことで、競合を避けました。

また、アセットも管理範囲毎に分離し、お互いが干渉しないようにしたそうです。その結果、チームごとに触るべきファイルが明確になり、お互いの衝突を減らすことに成功したとのことでした。

これは端的に言うと、モジュールの汎用化を諦めてしまったということですが、制作の体制によってはそのような解決策がベストになることもあるかと考えさせられた話でした。CSS設計の理想とはかけ離れていると感じる方もおられるかもしれませんが、このような諦めは、実際の仕事の中では有効な解決方法となることも多いのではないでしょうか。

汎用モジュールをベースとした設計

前項で挙げた事例のような、完全にチームが別れるなどしない場合でも、ECSSの「分離する」考え方は応用できるものと筆者は考えます。というより、Webサイトをモジュールベースで考えて設計していた場合、はじめは分けて考える必要がなかろうとも、運用していたら分ける必要が出てくるというケースは往々に発生するであろうから、基本的にECSSの「分ける」設計をベースにしておいたほうが、後々の保守性の向上の助けになるであろうと感じています。

筆者は以前、コーポレートサイトをワンストップで制作することの多い制作会社にて、フロントの実装を行っていました。その会社では、コンサルから設計、デザイン、コーディング、CMS組み込みまで全てやっているという制作体制を基本としていたことと、主に制作していたのがコーポレートサイトという、汎用的なUIパーツで大量のページを作る必要があるという状況があり、これを効率的にこなすため、どの制作工程においても汎用化されたモジュールでページを構成するという意識を共有することに、それなりに成功していました。

そのような制作体制の中、HTMLとCSSでテンプレートを作っていたのが筆者だったのですが、そのようにモジュール化を強く意識していた現場であったからこそ、汎用化されたモジュールが多くなりすぎてしまうという問題に頭を悩ますことが多くありました。

具体的には、トップページでしか使わないようなメインビジュアル、一部のキャンペーンページでしか使わない特殊なモジュールなど、おおよそ他のページで使わる可能性がないようなものであっても、汎用的なモジュールとして考えてCSSの設計を行ってしまっていました。

いや、むしろそのように「汎用的である」とか「そこでしか使わない局所的なものである」などという考えの元にCSSを設計していませんでした。BEMでいうBlockの集合でWebサイトを作っていましたが、ただそれだけで、とにかくなんでも使いまわせることを念頭に置いて設計を行っていました。

そのように、局所的にしか使わないモジュールを、汎用的なモジュールであると考えて設計してしまったことで、なにかCSSの容量が増えすぎてしまい問題になるというようなことは起こりませんでしたが、今考えればそれは、サイト全体で使う汎用的なモジュールらと、局所的に使うモジュールで分けて設計すべきでした。

例えば、汎用的なモジュールはsw-(SiteWide)、トップページだけで使うモジュールはtop-(Top)、キャンペーンページだけで使うモジュールはcamp-(Campaign)と名前空間を分けるなど。そのようにしておけば、前回までで紹介したように、トップページのみのリニューアルや、キャンペーンページの更新や削除にも対応しやすくなります。

そのように名前空間によりモジュールを分けるのは、一段階、モジュールのカテゴライズを設計する必要があることに注意する必要があります。ですが、基本的に汎用的なモジュールで構成されるようなWebサイトを作る場合でも、このようにECSSの考え方を適用しておくことは、将来の保守性向上へ貢献するのではなかろうかと筆者は考えます。

CSS設計のヒントはデザインカンプの外側にあり

そのように考えていると、もはやCSSの設計について考えることは、デザインカンプを眺めながらHTMLとCSSを書いているだけでは、ベストなゴールへ到達できない問題であるということに気付かされます。前項で上げたようにモジュールのカテゴライズを考えるということは、つまるところ、Webサイトを構成するモジュールをどのように考えるのかというところに辿り着き、画面の設計をどう考えるという設計に習う必要が出てきます。

また、どのようにモジュールを切るかという点について考えた時、HTMLとCSSを書いた後の工程へ目を向けることも重要かもしれません。例えばブログシステムに組み込むためのHTMLテンプレートを書く場合、そのブログシステムが、「ヘッダ」「フッタ」を、システム的にテンプレートを分離していて、それらのファイルをインクルードするような作りになっていたとしたら、HTMLとCSSでも「ヘッダ」「フッタ」を個別のモジュールとして用意することで、ブログのテンプレート組み込みとのモジュール感を一致させることができるでしょう。

プログラミングにおいて、同種の処理は共通化し、DRYを意識するのが、良い設計を行うための考え方の一つとして重要であることはよく知られているところです。OOCSSはそのような考えに習った設計思想でした。しかし、HTMLとCSSはプログラミング言語ではないことに注意しなければなりません。SassなどのCSSプリプロセッサやPostCSSの力を借りれば近いことができますが、行き過ぎた抽象化が保守のコストを高めてしまう可能性があるのでは?と、ECSSは考えさせてくれます。保守性を見越し、行き過ぎた複雑さを排除した、適切なモジュールの分離を目指すのがECSSです。

ECSSを取り入れるべきか否かは、プロジェクトの性質によって左右されるであろうと筆者は考えます。Webサイトは作って終わりではありません。サイトローンチ後も継続して変化しうるHTMLとCSSについての保守を考える場合、ECSS的な視点も考慮しつつCSSの設計を考えてみてはいかがでしょうか。

Powered byNTT Communications

tag list

アクセシビリティ イベント エンタープライズ デザイン ハイブリッド パフォーマンス ブラウザ プログラミング マークアップ モバイル 海外 高速化 Angular2 AngularJS Chrome Cordova CSS de:code ECMAScript Edge Firefox Google Google I/O 2014 HTML5 Conference 2013 html5j IoT JavaScript Microsoft Mozilla Node.js PhoneGap Polymer React Safari SkyWay TypeScript UI UX W3C W3C仕様 Webアプリ Web Components WebGL WebRTC WebSocket