デザインカンプを基に実装する難しさはあらゆる場面で語られます。私の場合は特にレスポンシブデザインに関する仕様の解釈に悩む場面が頻繁にあります。

その問題点はどこにあるのでしょうか。私の制作したツールの紹介を通して、グリッドシステムのあり方やレスポンシブデザインの意味などを考察しました。

デザインカンプとワークフローの関係性

ウェブサイト制作のワークフローでは、クライアントとの上流での合意形成と開発者への指示書との役割をデザインカンプが兼ねるパターンがよくあります。デザイナーはウェブページの実装仕様を決定しながらデザインカンプを制作し、開発者はデザインカンプを通して前工程での決定を読み取りながら実装します。

デザインカンプを基に実装する難しさの一因は、それがシステムが取り得る状態のうちの一場面を切り取った単なるスナップショットでしかない構造です。

システムはいくつもの状態を取り得ますが、デザインカンプはその一場面だけを切り取ったものでしかありません。

仕様を理解するためには、デザイナーが想定するイメージの片鱗であるデザインカンプからそのおおもとまで開発者がたどり着く必要があります。そのたどり着くべきゴールまでのパスを補完するのは、いかにデザイナーと開発者との「常識」が共通しているかという不文律です。

またデザインカンプ制作時の想定通り実装できたとしても、先の見通しが甘く、プロトタイプを見てから理想的に機能しないと悟る場面はよくあります。デザインカンプは技術的な意味で実際のシステムの制約を受けないため、あらかじめシステムの性質をよく理解できていないと的確なイメージが描けません。これは程度問題あれど防ぎようのない現象で、開発者である私自身、あまり開発経験がない仕様について実装を行わずに正確なイメージを持てる機会は稀です。

デザインカンプにまつわる問題が浮上するとき、このように不確実な想定の上で仕様を決定しなければならないワークフローの性質が何かしら関係しています。問題を回避するためには、実装を行わずともある程度正確なイメージを持てるようになるまで経験を積むか、実装を行いながら仕様を決定していくかしかありません。

自作ツールによる問題解決へ

実際の現場ではこの問題の解消は難題です。ほとんどの制作は専門分野ごとの分業の上に成り立っており、職責も職種ごとに区分されています。特定分野での働きだけを個別に取り出して評価される場合もあり、職種を越えたスキルの獲得が難しい状況にあります。

このようななかで別分野の学習に多くの時間を割くには無理があります。この状況を打開するために私は、自作のツールを通じて時間的コストと心理的負荷の削減ができないかを試みました。

ウェブページを実装するとき、HTMLやCSSのようなソースコードの読み書きは不可欠です。しかしながらこれはデザイナーにとって非常に大きな障壁でもあります。であればソースコードの読み書きなしにツールの(G)UIを通して実装に近い感覚を得られればよいと考えました。

ソースコードは規則の集まりを記述したものです。ウェブページとして見たとき、それぞれの言語の構文などは本質ではなく、どのような規則からいかにして画面が構成されているかが焦点です。そう考えると、ソースコードというインターフェースを介さずとも、目的である規則の集まりのようなものと触れ合う感覚を表現できる可能性が見えてきます。

つまりコーディングを通して得られるレスポンシブデザインの「触り心地」をツールでうまく表現できれば、ツールの操作を通して得られる非言語的な感覚によってレスポンシブデザインへの理解を助けられるかもしれません。その実現のためにレスポンシブデザインというテーマからさらに焦点を絞ります。

関心の抽出

ツール化の目的はソースコードからの「レスポンシブデザインへの関心」の抽出です。したがってブラウザの開発者ツールのようにCSSの宣言とそのまま対応する入力フィールドを作成しても的外れです。

CSSのセレクタとそれに対応する宣言ブロックが実装のソースコードの構文と対応する形で入力フィールドになっています。
Chrome DevToolsより

CSSのメタ言語であるSassには、宣言の集まりを定義して名前をつける@mixinという機能があります。@mixinによる名づけによって開発者は宣言の集まりに別の意味を与えられます。

たとえばCSSには三角形を描画させるテクニックがあります。しかしそもそもCSSは三角形を「記述として表現する」方法を持たないため、実装のためには開発者のメンタルモデルとあまり一致しないようなハッキーな手段を選ばざるを得ません。すると宣言には形式的な意味しか持たせられず、開発者の目的である「三角形を描画する」という意図がソースコードの記述上では薄れてしまいます。そこで@mixinを使った名付けを行うと、宣言の集まりと開発者の目的とが一致するようにリフレーミングできます。

@mixin downward-triangle($size, $color) {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 ($size / 2) $size ($size / 2);
  border-color: transparent transparent $color transparent;
}

.dropdown-icon {
  @include downward-triangle(8px, gray);
}

このような抽象化を計画的に行えば、宣言の裏に存在する考えがソースコードの記述として形になり、開発者の意図が明快に表現されたものになります。

ただしそれも利点ばかりではありません。@mixinによって宣言に名前をつけることは、宣言の意味を再解釈して別の言葉として定義する行為ともいえます。それゆえ他者の解釈を新たに理解する必要性が生まれ、場合によっては@mixinを介さないそのままの宣言の方が「正直」だと感じることもありえます。また言葉が秩序を持たなければ混乱や非効率性を招くでしょう。

ツール化についても同じです。CSSの世界観をうまく捉え直せていないとただ不自由なツールができてしまうし、CSSとまったく異なる表現になっていても混乱します。機能が増えるにつれてツール自体の学習は難しくなっていきます。

レスポンシブデザインにおけるコンテナの表現

私の経験では、デザインカンプの表現について大きく解釈の食い違いが生まれるシチュエーションは、ほとんどがページ内の要素を包み込む「コンテナ」に関係していました。コンテナの内側にある要素については、テキストの分量や画像サイズなどコンテンツに応じた変化であったり、コンテナに対する相対的なサイズであったり、文脈的な判断ができる手掛かりがあるため大きな問題にはなりません。一方コンテナはページのもっとも外側にあるため、どのように変化するか共通認識を持てるようになるまでは苦労します。

「ページ」がアートボードの全体を指しているのに対して、コンテナはその中のコンテンツ全体を取り囲みます。コンテナの外側には余白ができます。

基本的なレスポンシブデザインの手法では、コンテナの設計に大きく分けて2つのパターンがあります。コンテナの幅が流動的に変化するパターンと、任意の幅に固定されているパターンです。前者ではコンテナの幅はビューポートの幅に追従して変化し続けますが、後者では固定されます。またいずれのパターンであってもコンテナの幅の変化に応じてコンテナの中の要素は変化します。したがってレスポンシブデザインの制作では、デザインカンプ上で表現されたレイアウトの幅やアスペクト比が変化する性質を理解しておく必要があります。

この予備知識を持たないと、ページ内のすべての要素はコンテナの外側の余白も含めて常に同じアスペクト比を保ったまま伸縮するようにイメージしてしまう場合があるかもしれません。

デモ:コンテナの伸縮パターン

実装自体はそれでも可能です。ただしそうしてデザインカンプを引き伸ばしただけの実装では、多様な閲覧環境に合わせてデザインを調整できていません。すべての要素のサイズはユーザーの閲覧環境でなくデザインカンプを基準に設定されているといえます。結果として、デザインカンプのサイズに近い閲覧環境だけに向けて想定通りの最適なデザインを提供し、そこから外れるユーザーへの配慮は放棄する形になってしまいます。こういった実装は避けるべきです。

このようにデザインカンプを引き伸ばしたパターンではCSSの単位としてvwがよく利用されます。vwを用いた実装方法によっては、ブラウザのズーム機能やフォントサイズの変更機能が適切に動作しなくなるというアクセシビリティ上の問題が発生する場合もあるので注意してください。

ですがコンテナの幅が変化するのであれば、コンテナの中の要素の位置はデザインカンプ上ではどのように表現すればいいのでしょうか。レイアウトはデザインカンプの状態から変化するので、オブジェクトの座標の位置だけを手掛かりにすると解釈の違いが生まれてしまいます。

この問題を解決するのが「グリッドシステム」と「ガイド」です。

ウェブデザインではコンテナを任意の数に等分してレイアウトを決めるグリッドシステムを採用する機会が慣習的にあります。このグリッドシステムをデザインカンプ上だけで考えてしまうと、レスポンシブデザインの動的なレイアウトの変化を想定できず、アートボード上の静的なレイアウトを整理するためだけの仕組みになってしまいます。グリッドシステムをデザインカンプだけの都合で作るのではなく、レスポンシブに変化する実装を想定して作れば、それはデザインカンプから実装まで一貫して機能するシステムになります。

そしてデザインカンプにグリッドシステムと対応したガイドを引き、コンテナの中の要素の位置をガイドに沿わせることで、グリッドシステムと対応する座標にオブジェクトを配置する意図が表現されます。これにより実装時にコンテナの幅が変化した際にも、どの位置を基準に伸縮するかというデザインカンプが表現する状態以上の奥行きある情報を伝えられるようになります。

しかしグリッドシステムについての認識にズレがあれば意図通りに実装されません。こうした課題認識を踏まえて、私はレスポンシブなグリッドシステムをテーマにしたデザインツールを制作しました。

レスポンシブなグリッドシステムのためのデザインツール

レスポンシブデザインとしての振る舞いを理解するためには、「ウィンドウのリサイズ」を通してレイアウトの変化を連続的に観察するのが効果的です。検証方法として、ウィンドウをメジャーな端末のサイズに合わせてデザインを確認することがありますが、これはレスポンシブデザインの理解のためには向いていません。ウィンドウをリサイズする最中のレイアウトの観察を通して初めて実際の振る舞いを正確に理解できます。

このツールにおいてもウィンドウのリサイズ操作を中心に据えて設計しました。

また先述したように、グリッドシステムへの関心の抽出も意識しました。ツールでは、対応するCSSのソースコードデザインツールのガイドの設定とを出力する機能を実装しました。しかしユーザーの入力はそのどちらかだけに依存せず、デザインカンプとソースコードから抽象化された変数に対応します。これによりグリッドシステムがデザイナーと開発者の間に立つ共通言語になります。

レスポンシブグリッドデザイナーがデザインカンプとソースコードとの間に立ち、グリッドシステムをデザイナーと開発者とが意思疎通できる共通言語にします。

こうしたコンセプトで制作したのが「レスポンシブグリッドデザイナー」です。

レスポンシブデザインとCSS

レスポンシブグリッドデザイナーでは、ブレイクポイントごとのグリッドの設定をテーブルとして一覧できるようになっています。各設定の組み合わせは行として、ブレイクポイントをまたいだ値の変化は列として参照できます。

テーブルの中には行としてブレイクポイントごとの入力フィールドが並んでいて、列としては「最大幅」「カラム数」「ガーター」「マージン」「基準値」があります。なかでもブレイクポイントをまたいで値が共通している入力フィールドは行をまたいで縦にグルーピングされています。

テーブルの中では、行をまたいで共通している値は視覚的にグルーピングされています。これらはそれぞれ別のブレイクポイントにおいて適用される値なので、一見関係性はないように思えます。ですが実はこのグルーピングの表現には、CSSやレスポンシブデザインの考え方を反映しています。

レスポンシブデザインの目的は、特定の端末サイズや機能に依存しないデザインの実現です。ひとつの端末だけに最適化したデザインをしていても、市場の変化やユーザーの性質によって閲覧環境は多様になっていくので、幅広いユーザー層に価値を届け続けることができません。対してレスポンシブデザインの手法では、特定の端末への最適化を避け、幅広い閲覧環境でシームレスに機能するデザインを目指します。対応環境を個別に増やしていくような考え方ではなく、そもそも多様であることが問題にならないようにデザインします。

デザインカンプとしては、アートボードごとに個別のデザインをするのではなく、ひとつの同じデザインを閲覧環境に合わせて「部分的に調整」していくという方がレスポンシブデザインの意図に合っています。このアプローチはCSSとの親和性が高く、これを堅牢かつ効率的に実現できる機能がCSSには備わっています。

CSSには文脈に応じて宣言の組み合わせが引き継がれていく仕組みがあります。次のように、宣言がそれぞれ別のブロックに記述されていても対象の要素には両方の宣言が組み合わさった結果が適用されます。このような仕組みをカスケードと呼びます。

h1 {
  font-size: 32px;
}

h1 {
  line-height: 1.5;
}

カスケードされた結果:

font-size: 32px;
line-height: 1.5;

レスポンシブデザインではメディアクエリという規則を記述します。端末のサイズや機能に基づいて処理を分岐させるために利用できて、CSSにおいては特定の宣言を適用させるかどうかを決めるために利用します。たとえば次のCSSでは、閲覧環境の幅が1024px以上であればfont-size: 64px;を適用しますが、1024px未満であれば適用しません。

h1 {
  font-size: 32px;
  line-height: 1.5;
}

@media (min-width 1024px) {
  h1 {
    font-size: 64px;
  }
}

幅が1024px以上:

font-size: 64px;
line-height: 1.5;

幅が1024px未満:

font-size: 32px;
line-height: 1.5;

カスケードの利用によって、基本的な宣言は受け継ぎつつも調整する必要がある部分のみを個別に上書きする形で――つまりレスポンシブデザインの手法と対応する形で規則を層として重ねていくことができます。そのままでよい値は繰り返し記述せずとも引き継がれていく性質がCSSの特徴です。レスポンシブグリッドデザイナーのテーブルではこのカスケードをグルーピングによって表現しています。

ちなみにSassには、セレクタのブロックの中にメディアクエリを入れ子にできる機能があります。Sassを利用してCSSを書くとき、私は必ずこの記法を利用して、セレクタを先にメディアクエリを後に考えます。これはソースコードの記述としてもレスポンシブデザインの意味を強調するためです。セレクタとして表現する対象の要素の方が基準であり、メディアクエリとして表現する文脈に応じて細部が調整されていきます。極論を述べれば、メディアクエリが先に来た時点でレスポンシブデザインではなくなってしまいます。

h1 {
  font-size: 32px;
  line-height: 1.5;

  @media (min-width: 1024px) {
    font-size: 64px;
  }
}

ロジックとレイアウトを繋ぐもの

レイアウトはいわば「絵」です。具体的な形をともなってはじめて評価できます。一方でソースコードは「ロジック」です。形の定まらない抽象的な問題を取り扱います。

CSSではロジックとして絵を表現します。抽象的な宣言を介して個別の形を作ります。CSSだけに限らず、UIデザインではあらゆる意味で個別の形を作るためのロジックが要求されます。

デザインカンプと実装の溝は、この2つの性質を掛け合わせる難しさにあります。

そして溝を埋めるための建設的な議論をするためには、それぞれの性質についてそれぞれの担当者が共通したイメージを持てなければいけません。レスポンシブグリッドデザイナーではコーディングを介さずともグリッドシステムのロジックに触れられるインターフェースを目指しました。これによってデザイナーがロジックを理解できれば、開発者との共通したマインドセットを持つためのきっかけになるはずです。

私がCSSを書くとき、これら2つの性質について視点を行き来させている感覚があります。あるときは絵を描いていて、あるときはロジックを組み立てています。その最中で、ふとその「どちら側」にいるかをまったく意識しなくなる瞬間があります。感覚の上ではそれらの境界がなくなって一体化しているように思えます。

しかし分業している以上、作る側の感覚が分断してしまうのは防ぎようがありません。それでも、ひとつの制作物を統一した世界観のまま完成させることは可能なのか。なにがその実現を妨げるボトルネックになっているのか。制作の意味を前進させるために、この問題については意識し続けざるを得ないでしょう。

参考資料