2011-12-15

レスポンシブ対応に使えそうなLESS/Sassの書き方

Responsive Web Designを考えたCSSコーディングに役立つLESS/Sassのコードを紹介します。

LESS/Sassの前にResponsive Web Designの定義の話

まず先にResponsive Web Designとはどういうものであるかを確認しましょう。
Ethan Marcotteが提唱したResponsive Web Designは、次の3つの要素で構成されたものとなります。

  • A flexible, grid-based layout,(柔軟で、グリッド型のレイアウト)
  • Flexible images and media,<(柔軟な画像・メディア)
  • Media queries,a module from the CSS3 specification.(CSS3 メディアクエリ)

今回の記事でおさえたいことはFlexible/Fluid(流動的)なレイアウトであることです。例えばCSSでカラムの横幅をwidth:300pxというような固定幅でレイアウトするのではなく、width:31.25%というような相対値による指定でレイアウトする必要があります。これによりデバイス、ブラウザウィンドウの幅問わず、コンテンツがその割合で収まるようになります。

デモではウィンドウサイズを960pxよりも狭くしてみてください。横スクロールが発生せず、コンテンツがそのウィンドウサイズ内に収まるようになるはずです。

DEMO

幅をパーセンテージにする

以下サンプルコードです。ページ・カラムの幅を固定させた場合と、パーセンテージにした場合の2種類のをLESSとSassそれぞれで書いた場合のコード例です。

Sass

// Variable
$page: 960px; /* ページの幅 */
$column: 300px; /* カラムの幅 */

// Mixin
@mixin responsive($count:1){
  width: percentage($column / $page * $count);
}

// Fixed Layout
body {
  width: $page;
}
[role="main"] {
  width: $column * 2;
}
[role="navigation"] {
  width: $column * 1;
}

// Fluid Layout
body {
  width: 100%;
  max-width: $page;
}
[role="main"] {
  @include responsive(2);
}
[role="navigation"] {
  @include responsive(1);
}

LESS

// Variable
@page: 960px; /* ページの幅 */
@column: 300px; /* カラムの幅 */

// Mixin
.responsive(@count:1){
  @percent: (@column / @page * @count) * 100;
  width: ~'@{percent}%';
}

// Fixed Layout
body {
  width: @page;
}
[role="main"] {
  width: @column * 2;
}
[role="navigation"] {
  width: @column * 1;
}

// Fluid Layout
[role="main"] {
  .responsive(2);
}
[role="navigation"] {
  .responsive(1);
}

これらをコンパイルすると、次のようなCSSになります。

CSS

// Fixed Layout
body {
  width: 960px;
}
[role="main"] {
  width: 600px;
}
[role="navigation"] {
  width: 300px;
}

// Fluid Layout
body {
  width: 100%;
  max-width: 960px;
}
[role="main"] {
  width: 62.5%;
}
[role="navigation"] {
  width: 31.25%;
}

ポイントはLESS/Sass両方のMixinの部分になります。

// Sass Variable
$page: 960px; /* ページの幅 */
$column: 300px; /* カラムの幅 */

// Sass Mixin
@mixin responsive($count:1){
  width: percentage($column / $page * $count);
}
// LESS Variable
@page: 960px; /* ページの幅 */
@column: 300px; /* カラムの幅 */

// LESS Mixin
.responsive(@count:1){
  @percent: (@column / @page * @count) * 100;
  width: ~'@{percent}%';
}

あらかじめページおよびカラムの幅を定義し、その値を利用して幅の値をパーセント化します。この例では、最大横幅960pxとし、コンテンツ部分のカラム幅を300pxとしています。そのカラム幅をページ幅で割ることで、ページ幅に対するカラム幅が相対的な値が算出されます。またMixinでは引数にカラム数を渡すことで、それに応じた幅になるようにしています。この例では単純に、1カラムあたり300px相当になるのを、2(つまり2カラム分)とすることで、600px相当になるわけです。デモではサイドバーを1カラム分、メイン部分を2カラム分にしています。

ここのコードを見て気づいたかと思いますが、LESSの場合にはパーセンテージにするために、100をかけたり、パーセント単位をつけるための記述が必要ですが、Sassにはpercentage()という関数が用意されているので、今回のようなケースでは非常に楽に使うことができます。このあたりはSassに若干アドバンテージがある部分でしょうか。

まとめ

レスポンシブウェブデザインに使える、という前フリではありましたが、今回は絞って解説をしました。実際には柔軟なグリッドレイアウトのために、カラム間の余白なども計算する必要がありますが、それらも相対値になるように上手く計算されるように仕込むと、レスポンシブなレイアウトを実現することができます。発想次第で色々とできるので、是非試してみてください。