CSSとLESSでの階層構造の考え方
今回は技術的なLESSの文法から少し離れて、効率的なLESSファイルの分割の仕方や構造について考えてみましょう。
本連載の第2回の「インポート ~ほかのCSSを読み込む」で解説をしたように、LESSではコンパイルする際、インポートしたファイルが1ファイルにまとめられます。そのため、多くのファイルに分割してもサーバーへのリクエスト回数が増えず、その分読み込みを高速に、かつ製作者の都合の良いようにファイルを管理することができます。
大枠ではCSSとLESSであまり差がないのですが、より機能や役割に特化した形で分割できるようになったと言えます。
サービスやサイトの性格にもよって変わってきますが、今回は大きく以下2つのパターンを考えてみましょう。
- (1)サイト全体を通して最低限の容量のCSS(LESS)を、分割した複数ファイルで読み込む構成
- (2)1ページごとに最適化したCSS(LESS)を、1ファイルのみ読み込む構成
(1)サイト全体を通して最低限の容量のCSS(LESS)を、分割した複数ファイルで読み込む構成
大きく分けて、下記の2種類のファイルに分けて読み込むことを想定したLESSファイルの構成を考えてみました。
- ページごとの固有のCSS(ある場合)
- サイト共通のCSS
/common.less:全ページ共通パーツなどを「common.css」に変換
/page_name.less:ページごとの固有CSS「page_name.css」に変換(page_nameはページごとに変更)
└ /import/:common.lessへのimport用のディレクトリ(この中のLESSファイルはcssに変換しない)
├ /import/reset.less:HTML5 Doctor CSSなど、ブラウザの誤差吸収のためのCSS
├ /import/mixin.less:LESSから参照するmixinを集めたファイル
├ /import/variable.less:LESSから参照する変数を集めたファイル
└ /import/config.less:ブラウザ対応(-webkit/-mozなど)を設定するためのファイル(本連載の第7回を参照)
1つのhtmlファイルから実ファイルとして参照されるCSSは、common.lessとpage_name.lessを変換した、2つのCSS(common.css、page_name.css)となります。
普段CSSでコーディングをしている方は、おそらく自然とこのような形でファイルを分割しているのではないでしょうか。
はじめは複数回のリクエストが発生してしまいますが、common.cssはキャッシュされるため、サイト内で回遊することが想定されるWebサイトであれば、結果として読み込む容量が少なくなるため、非常に有効です。
このように、機能ごとに細かくファイルを分割しても、生成する際にまとめてくれるのはLESSの大きなメリットと言えます。
(2)1ページごとに最適化したCSS(LESS)を、1ファイルのみ読み込む構成
サイト全体が先ほどの(1)の構成のファイルを単純に連結するだけでは「ページごとに最適化している」とは言えません。そこで、LESSの特性を活かして、少し凝ったファイル構成を作ってみました。
結果として、「HTML1ページあたり、1ファイルしか読み込まない!」という、非常に男らしい構成となりました。
/page_name.less:ページごとの固有CSS「page_name.css」に変換(page_nameはページごとに変更)
└ /import/:page_name.lessへのimport用のディレクトリ(この中のLESSファイルはcssに変換しない)
├ /import/common.less:ページ間で共通のパーツなど
├ /import/reset.less:HTML5 Doctor CSSなどのブラウザの誤差吸収のためのCSS
├ /import/mixin.less:LESSから参照するmixinを集めたファイル
├ /import/variable.less:LESSから参照する変数を集めたファイル
└ /import/config.less:ブラウザ対応(-webkit/-mozなど)を設定するためのファイル(本連載の第7回を参照)
先ほどの構成と変わったのは、page_name.lessとcommon.lessの役割です。
(1)の構成では、common.lessが基点となって各ファイルをインポートしていました。一方こちらでは、page_name.lessを基点として考え、common.lessはインポートされる側のファイルとして用意してあります。
これだけではcommon.lessとpage_name.lessを結合しただけのものになってしまうので、さらにそこからcommon.lessの最適化を考えてみましょう。
common.lessの中身は、おそらく「ページ間で共通で使われるもの」ですが、「全ページでは使わない」ものもあるのではないでしょうか。
そこで、common.lessの中身をパーツ単位でmixinにして、分割してしまいましょう。
たとえばcommon.lessの一部が下記のようになっていたとします。
「header、footer、#globalNavは全ページで使うけれど、.infoContents、.userListは特定のページでしか使わない(でも複数のページにまたがって使う)」という前提をもとに、グルーピングしてみましょう。
違いがわかるでしょうか。
- 全ページで使うheader、footer、#globalNav
- ⇒#allPagesというidで囲み、mixinに
- 特定のページでしか使わない.infoContents、.userList
- ⇒#individualPagesというidで囲む
その後それぞれ、.infoContents、.userListというmixinを作りました。
あとは、mixinをページごとのLESSファイルで必要に応じて呼び出すだけです。
(mixinのグルーピングについては、本連載の第6回の「mixinのセレクタを用いてグルーピングをする」をご参照ください)
たとえば、トップページですべて共通するheader、footer、#globalNavと.infoContentsを使う場合は、以下のようにして呼び出します。
こちらのファイルをコンパイルすると、以下のようになります。
必要な箇所だけtop.cssで読み込むことができ、かつcommon.lessで集中管理できるようになりました。
これはCSSを1つのファイルにまとめることに特化した、いわば「特定のページしか見ないユーザー」に向けた極論的な方法ではあります。しかし、たとえばランディングページのように、検索エンジンなどから特定のページへ直接訪問してくる導線で、かつ少しでも速く表示したいという場合には非常に有効です。
ただ、ユーザーが複数のページにわたり遷移する場合は、結果としてcommon.lessの中にあるコードを重複して何度も読み込むことになるので、注意してください。
ケースに応じてより効果的な分割管理を
場合によっては、common.lessのインポート方法をページごとのLESSファイルで変えることにより、(1)と(2)の両パターンの利点を活かしたハイブリッド構成も可能です。
- サイト内で特集ページは(2)のパターンを使う
- 他のページでは(1)のパターンを使う
という方法も、サイトの構成によっては非常に有効だと思います。
今回の分割管理の方法は、あくまで一例です。小規模なサイトであればここまで分割する必要はないかもしれませんし、大規模なポータルサイトならばもっと階層構造を深くして、全共通/サービス共通/ページ固有などと分割する形も考えられます。ぜひ、自分が担当するサイトやアプリの特性に合わせた構成を考えてみてください。
次回は最終回です。LESSを書くのに便利なツールやアプリを紹介しますので、お楽しみに。