本連載では、Enduring CSS(ECSS)というCSS設計方法論を紹介しています。
前回は、ECSSの考え方の特徴と、Module、及びその内容について見てきました。今回は、Namespace(名前空間)とアセットの分離について解説します。
Namespace(名前空間)
ECSSの大きな特徴の一つに、Module群をNamespace(名前空間)でまとめるという点があります。前回解説したクラスの命名規則だったり、実際のWebサイト上で使われているクラス名には、名前空間を示す接頭辞がついていました。
以下に、前回登場したクラス名の一部を列挙します。括弧内の文字列が、Namespaceです。(各モジュールがどういうものかは、第一回目の終わりに紹介したECSSサイトのトップページのモジュール一覧をご覧ください)
home-Benefits
(home): ECSSの利点をまとめているモジュールhome-Testimonials
(home): ECSSの推薦コメントをまとめているモジュールst-Nav
(st): ヘッダ部にあるナビゲーションのモジュールst-Footer
(st): フッタのモジュールhero-Standard
(hero): ヒーローエリアのモジュール
上記であれば、home-Benefits
とhome-Testimonials
はhome
に、st-Nav
とst-Footer
はst
に、
hero-Standard
はhero
に属するという具合です。
なお、ECSSには、クラス名上でのNamespaceは、単語の頭文字らをとったりして略称にすると良かろうと書かれています。書籍の内容によれば、ここで登場しているst
というのは、Structure
を意味し、ヘッダやフッタなど、サイト共通の基本構造的なModuleを属させているようです。
セレクタの競合を回避するNamespace
このように、Moduleを必ずNamespaceに属させる意味としてはまず、セレクタの重複を避けるという点が大きくあります。
どのようなCSS設計方法論を用いていたとしても、ECSSでいうModuleの名前をどうするかという点に頭を悩ませることが多いのではないでしょうか。筆者は数多くのWebサイトをコーディングしてきましたが、この名前付け作業にはいつも多くの時間をかけていました。今後どこかで使われることを見越し、どういった名前にしようかなどと考えると、最適な名前はなんだろうかと悩むのです。
ECSSは、Moduleを必ずNamespaceに属させるというルールにしています。そして、前回解説したように、Moduleのクラス命名規則が
1 |
namespace-Module |
であり、Module内の要素にスタイルを当てたい場合は、その要素をChildNodeとし、
1 |
namespace-Module_ChildNode |
とクラス名を付け、そのクラスセレクタでスタイルを当てるルールになっています。なので、Moduleの名前をそのNamespace内で重複しないようにさえしておけば、別のModuleのセレクタと競合することがありません。
例えば、前回例に出したBenefits
というModuleは、Namespace home
に属します(home-Benefits
)。home
というのは、このサイトを眺める限り、トップページで使うModuleらをまとめるために使用されているように見受けられます。とすれば、トップページの中で重複しないModule名であればそれで良いのです。
どこかでBenefits
という名前のModuleが登場したとしても、それは別のNamespaceでの話です。hoge-Benefits
などという、別のNamespaceを示す接頭辞から始まるクラスセレクタでスタイルが当てられるでしょうから、セレクタの競合を恐れる必要はありません。
もちろん、このように深く考えないで良いという前提としては、前回解説したように、例え似たようなModuleがどこか別のところ(この場合ですとトップページ以外)で登場しても、そのためには別のセレクタを書き、別にスタイルを当てるという、CSSの重複を許す諦めがあってのことです。
Namespaceの切り方
では、具体的にどういう風にNamespaceを用意したら良いのでしょう。ECSSでは、Namespaceの切り方として、ショッピングカートを例に挙げています。ショッピングカートの仕組みを作るのであれば、sc
という、ShoppingCartを略したNamespaceを用意し、そこで使われるModule群をsc
に属させるようにするという具合です。
この例を、もうちょっと発展させて考えてみます。
- トップページ
- 商品詳細
- ショッピングカート
という3つのテンプレートで構成されるサイトがあったと仮定します。この場合、例えばこんな風にNamespaceを分けてしまうのはどうでしょう。
トップページで登場するModuleは全てtp
(topPage)に、商品詳細で登場するModuleは全てpd
(productDetail)に、ショッピングカートで登場するModuleは全てsc
(ShoppingCart)に属させるという具合です。
しかし、大抵の場合、ヘッダやフッタはサイト全体で共通のものになっていることでしょう。ほかにも、サイドナビにある広告エリアがどのページでも共通であるような状況を想像してみてください。そんな時は、共通Moduleをまとめるcmn
(common)というNamespaceを用意してみてはどうでしょう。
cmn
に、ヘッダやフッタ、サイドエリアの広告エリアを属させるのです。
例えばこんなModule名で。
cmn-Header
(ヘッダ)cmn-Footer
(フッタ)cmn-SideAd
(サイド広告)
これは、あくまでテンプレートの種類でNamespaceを切るというひとつの例にすぎませんので、当然、必ずテンプレートごとにNamespaceを用意せよというわけではありません。Namespaceの切り方は設計者次第であり、自由です。
このようにECSSでは、Namespaceを切ることで、セレクタの重複を防ぎます。Namespaceをどう切るかという設計は必要になりますが、Moduleの名前を考えるのは、かなり気軽になるのではないでしょうか。
アセットの分離
ECSSでは、Namespaceごとに、そのNamespaceに属するModule内で使用するCSS、JS、SVG、画像等のリソースを分離してしまうのが良いと考えています。本連載では、便宜上、これらのリソースのことを「アセット」と呼ぶことにします。
普段Webサイトを作る時、例えば以下のようにCSSやJSファイルを一つにまとめて管理したり、
1 2 3 4 5 |
/src ├── css │ └── styles.css └── js └── app.js |
機能やModuleごとにCSSやJSファイルを作り、アセットの種類ごとにディレクトリを作り、ファイルをまとめたりしていませんでしょうか。
1 2 3 4 5 6 7 8 9 |
/src ├── css │ ├── ProductDetail.css │ ├── ShoppingCart.css │ └── TopPage.css └── js ├── ProductDetail.js ├── ShoppingCart.js └── TopPage.js |
ECSSでは、ファイルタイプ別ではなく、Namespace別にアセットを管理します。前例の
- トップページ – TopPage
- 商品詳細 – ProductDetail
- ショッピングカート – ShoppingCart
だと例えば、以下のような形になるかもしれません。
1 2 3 4 5 6 7 8 9 10 |
/src ├── ProductDetail │ ├── ProductDetail.css │ └── ProductDetail.js ├── ShoppingCart │ ├── ShoppingCart.css │ └── ShoppingCart.js └── TopPage ├── TopPage.css └── TopPage.js |
各Namespaceのディレクトリ配下は、もっと好きなように便利に管理して良いのですが、重要なのは、Namesapce毎にアセットを分けて管理するという所です。
ECSSでは、このように分けたアセットらを、必要に応じてビルドしてまとめたりして使うよう、想定しています。
アセットの分離がもたらすメリット
Namespace毎にアセット分けられていると何が嬉しいのでしょうか。先述した、Namespaceの切り方として挙げた例をベースに考えてみます。
探しやすさ
アセット分離のメリットとしてはまず、どこにアセットがあるのか探しやすいという点が挙げられます。
例えばトップページの、以下のヒーローエリアへ配置されたtp-HeroImage
というModuleの、CSS/JS/画像を探したいとします。
この場合、Namespaceごとにアセットが管理されていたとすると、このModuleに関するアセットは、トップページのアセットがまとめられているディレクトリ内にあるはずです。トップページのアセットを、/topPage
(tp
)に置いていたとしたら、このModuleのアセットもその中にあることが分かります。また、新しく画像やJSを追加したい場合でも、このディレクトリの中に置けばよいということも分かります。
捨てやすさ
見つけやすいという点は重要ですが、何にも増して重要なのは、使わなくなったアセットを捨てられるという点です。
CSSを書いていると、一度書いてしまったルールセットは二度と消せないと感じないでしょうか。自分一人で書いていたならまだしも、複数の人間がひとつのWebサイトのCSSを編集していたら、自分が書いていないルールセットを編集したり、消したりするのには細心の注意が必要です。ECSSの「アセットの分離」というアプローチは、これを解決する一つの方法です。
例えば、トップページのデザインをリニューアルしたいと仮定します。
この場合、それまでトップページで使っていたModule群はもう不要となるでしょうから、当然、そのModule内で使用していた画像なども不要になります。
このような場合、トップページ上のModule群をNamespace tp
(topPage)に属させていたとして、そのアセットを/topPage
に配置していたとすれば、もう過去のトップページのアセットは不要であると判断される場合、この/topPage
ディレクトリごと消してしまえばよいのです。
そしてリニューアルされたバージョンのトップページで使うModule群は、Namespace tp2
(topPage2)に属させることにします。そして、そのアセットを/topPage2
に配置することにしましょう。
結果として、リニューアル前のトップページで使用されていたCSSや画像などは、どこにも残りません。
もし、トップページで使っているModule群が、他のページでも使えるよう、汎用的なModuleとして作られていたとしたら、このように、簡単に消すことはできないはずです。そのように汎用的に作ってしまったModuleは、永遠にWebサイトのCSSの中に残り続ける運命にあります。
また、前回解説した、「抽象化を避ける」という点についても思い出してみてください。もしOOCSSで言うレゴのように、細かな汎用的なModuleが沢山トップページで使用されていた場合、このように古いModuleを簡単に消すことができるでしょうか。きっと、使われていないModuleを一つ一つ吟味し、慎重に消すことになるでしょう。
何を重要とするかはプロジェクトにより異なるでしょうが、ECSSは、このようにNamespace毎にアセットを分離することで、運用にシンプルさをもたらし、永続的にCSSを運用していく事ができるようになると考えます。
今回は、名前空間とアセットの分離について解説しました。次回は、ここまでで紹介していないトピックのうち、いくつかを選んで紹介します。