Web Componentsの粒度とCSS設計について

本記事では「Web Componentsとは何か」ということや実装方法については述べません。また答えはでません。

コンポーネント粒度についてAtomic Designをベースに書いていますので、Atomic Designを知らない場合は「珍しいワークフロー:Atomic Designの原則とSketchでデザインからプログラミングまで」を先に読んでいただけますと幸いです。

コンポーネント粒度

コンポーネント粒度について考えます。Custom Elementsは、粒度については実装者に任されています。この粒度についての視点は2つ考えられます。

  • 再利用可能性(何箇所で使いまわすか)
  • HTMLを文章構造としてみるか(JSで隠蔽するか)

ひとつめの「再利用可能性」はCSS設計でさんざん言われてきました。同じボタンでも、ページAでのborder-radiusは2px、ページBでは3px…だとすべて別コンポーネントになります。同様にページAではパーツA/B/Cが入ったものが1コンポーネント、ページBでは…という設計もコンポーネントを増やす要員になり共通化できません。そこで、使いまわす回数とWebサイトの成長を見据えてコンポーネントの粒度・共通化を決めます。

ふたつめの「HTMLを文章構造としてみるか」は、1.JS無効環境で表示できない文字列を許容するのか / 2. それってSPAと同じ検索エンジン問題抱えるよね、という点です。`<button>ボタン</button>`は、JS無効環境下でも「ボタン」という表記は残ります。しかし、これをラップした`<submit-button></submit-button>`というCustom Elementsを用意すると、JS無効環境下ではテキストは反映されません。これを許容するかです。

それを踏まえると、コンポーネント粒度は大きく2つに分けることができます。

分子単位の設計

別名「脱div地獄」。インテントが深くなっていく装飾のための要素をすべて内包し、場合によってはクリックイベントなどのアニメーションもすべて内包するする形です。
Onsen UI 2の`ons-button`をみていただくとわかりやすいです。必要な文字列以外の情報(役割など)はattributeで渡してしまい、デザインに関する部分はラップしています。けれど、テキスト部分はHTML上に書きますのでJSによって隠蔽されません。

https://ja.onsen.io/v2/api/js/ons-button.html

CSS誕生時に「文章構造と装飾の分離」が掲げられましたが、それを一歩進めた形ですね。

有機体単位の設計

現実問題としてWeb Componentsを使い始めると分子単位に留めない選択肢もあります。ヘッダー部分(WordPressでいう`wp-head()`)など各ページで共通化するものをすべてWeb Componentsにしてしまう「大きな単位での粒度」です。
確かに、再利用可能性は高い。ちょっと昔でいうとiframe、最近ではいうとpugなどを使わなくてもWeb標準で共通化を行うことができます。ただ、多くの場合は文章構造まで隠蔽されることになるでしょう。

CSS設計

コンポーネント粒度を二分すると、CSS設計も自ずと見えてきます。大きな点として「Shadow Domを使うか否か」です。私達は大規模な設計をするほど、CSSの「カスケーディング」に苦しめられてきました。挙句の果てに`!important`を多用する暴挙も聞きます。

けれど、分子単位のコンポーネント粒度にShadowDOMを使うのは現実的だとは思えません。理由は以下の通りです。

  • グローバル変数を読み込めなくなるので、デザインの統一性がSCSS登場以前になる(タスクランナーがんばる?)
  • #host::が多用される未来が想像できてしまう
  • 過去の資産は使えなくなる(CSSフレームワーク含めて)
  • カスケーディングでなくなるって応用性効かなくなることだよ?

まだ私はカスケーディングを嫌いになりきれていないというところもありますが、分子単位でShadowDOMを使うのにグローバル変数読み込むのはちょっと違うなと思っています。コンポーネント群を接頭語にしたBEMかFLOCSSで書いたらどうにでもなるなと。

どちらかというと、Shadow DOMが活躍するのは、有機体で設計されたCustom Elementだと思っています。ヘッダーでしか使わないデザインが他に波及した、サイドメニューのみのボタンデザインが気づいたら…ということはよく起きることではないでしょうか。また、有機体で設計されている場合は、「有機体を丸ごと捨てる」ということが楽に行うことができます。今まで、修正を繰り返してきてCSSの残滓が残っているということはよくある話でしたが、これをWeb Componentsにすることによってまとめて捨てることができます。よく言われる「コンポーネント毎のデザイン」というのは保守まで見据えるとこういう形なのではないでしょうか。

カスケーディングは滅びるか

滅びないのでは。それよりは、グローバル変数とカスケーディングをきかせる要素、そして効かせずにコンポーネント毎にデザイン・保守する要素と細分化が進むと思っています。

Web Componentsは何を変えるか

個人的な感想としては、Web Componentsが現場を変えるのは有機体の粒度で設計された場合だと思っています。デザインの共通化ルールの強化、Componets単位での保守、そして「丸ごと捨てる」という今までと違った保守体制とどれをみても現場として新しい光だと思っています。

ただ、HTMLとしてみた時に、JSにテキストまで内包されてしまっているのは違和感がある。マナーが悪いとまではいいませんが、それだったらSPAにしてもっとユーザ体験を突き詰めた方がプロダクトとしていいのではないか感もありますので答えはでませんが、何らかの参考になりましたら幸いです。

それではまた。

お問い合わせ