デザインデータに忠実にCSSコーディングするためのテクニック

こんにちは、Webフロントエンドエンジニアの権守です。 フロントエンドエンジニアの皆さんは、リリース前の社内QAにてデザイナーにピクセルのずれを指摘されて修正したという経験があるのではないでしょうか。今回はiQONのPC・スマホサイトを構築する上で、デザインデータに忠実なCSSコーディングをどのように実現しているかを紹介します。

f:id:vasilyjp:20170202154557j:plain

ツールの利用

PerfectPixel

既に利用されている方も多いかもしれませんが、デザインとのピクセルずれの確認にはPerfectPixelがオススメです。 PerfectPixelは、画像を透過して重ねることでデザインとのずれを確認できるブラウザ拡張です。シンプルですが、透過率の設定や画像の拡大縮小、オフセットの設定など必要な機能をしっかりと備えており、使いやすいです。 複数のブラウザ(Chrome, Firefox, IE, Safari, Opera)で提供されているというのも嬉しいところです。

f:id:vasilyjp:20170202164756p:plain

重ねるとピクセルのずれや文言違いが一目でわかるのが伝わるかと思います。

Sketch

Adobe Fireworksの開発が終了して以来、VASILYでは、デザインデータはAdobe Illustrator, Adobe Photoshopを使って作成されていました。 しかし、元々Webデザインを行うことを目的に作られていないこともあり、エンジニアにとって使いづらく、実装時の障害になっていました。また、サイトの大規模化に伴いUIコンポーネント管理も問題となっていました。 そこで、VASILYでは、デザインと実装の効率化を図るために昨年夏ごろからSketchを導入し始めました。 Sketchは、WebデザインやアプリデザインなどのUIデザインに優れたデザインツールです。 シンボル機能を使ったUIコンポーネント管理や、オブジェクト間の距離の表示、ワンクリックでの画像の書き出し、デザインプロパティのCSSプロパティへの変換など便利な機能が豊富にあります。 また、有志の方々により高機能なプラグインも多く開発されている点も魅力的です。

f:id:vasilyjp:20170202154801p:plain:w300 f:id:vasilyjp:20170202154822p:plain:w300

導入にはデザイナーの協力が不可欠ですが、導入できる方にはぜひおすすめしたいです。

コンポーネント化

PerfectPixelを使っているとデザインとの小さな乖離でも気になるようになってきます。そのような乖離を減らすためには、デザイン側と実装側の両方でコンポーネント化が必要になってきます。 デザイン側はSketchの導入によって、シンボル機能を用いてのコンポーネント化を行いました。 実装側では、以前、本ブログでも紹介したようにSassのMixinという形でコンポーネントを管理しています。デザイン側でもコンポーネント化が進んだことによって、どこまでがpaddingでどこからがmarginかといったことがわかるなど、より適切にコンポーネントを把握することができようになりました。それによって、デザインとの乖離が減ったのはもちろん、実装時の迷いも減りました。 コンポーネントの例を以下に示します。

f:id:vasilyjp:20170202154852p:plain

brand_link_list.sass

@mixin m-brand-link-list($mright, $column: 3, $size: medium)
  $link-width: 0
  @if $size == large
    $link-width: 312px
  @else
    $link-width: 251px
  ul.m-brand-link-list
    margin-top: -4px
    padding-bottom: 4px
    li
      display: inline-block
      background: url($cdn-domain + "shared/link_icon.png") no-repeat 3px 7px
      vertical-align: top
      $pleft: 15px
      width: $link-width - $pleft
      padding: 0 0 33px $pleft
      margin-right: $mright
      &:nth-child(#{$column}n)
        margin-right: 0
      a
        color: $link-color
        font-size: 14px
        line-height: 22px
        &:hover
          text-decoration: underline
          padding-bottom: 1px
        .sub
          font-size: 10px
          line-height: 16px
          margin-top: 3px

モックデータの管理

デザインデータ上のテキストはモックが入力されています。そのデザインに合わせてコーディングを行っていると、デザインに合わせることに夢中でコードレビュー前に実際のデータに戻し忘れてしまうということがあります。 そこで、以下のようなRailsのヘルパーを実装しました。

application_helper.rb

...

def apply_mock(original, model_name, key)
  return unless Rails.env.development?
  mock = YAML.load_file(Rails.root.to_s + "/config/mock/#{model_name}.yml")[key]
  if original.is_a?(Array)
    original.clear.concat(mock)
  elsif original.is_a?(Hash)
    original.merge!(mock)
  end
end

...

config/mock/users.yml

:my_page_design:
  :nickname: 'ゴンノカミ'
  :email: 'hoge@vasily.jp'

mock_sample.html.slim

- apply_mock(@user, :users, :my_page_design)
section
  h1 = "#{@user[:nickname]}さんのマイページ"
  p = @user[:email]

YAMLから読み込んだデータで元のデータを表示前に上書きします。試験導入中なので、実装はシンプルなものになっていますが、十分に効果を発揮しています。コミットする際にはapply_mockをコメントアウトする運用をしてますが、もし、コメントアウトし損ねてしまったとしても開発環境でしかデータを上書きしないようにしてあります。

現状は、表示側をデザインに合わせていますが、Craftなどのプラグインを使ってSketch側でデザインをAPIに合わせるという方法も有効だと思います。

Tips

最後に忠実なCSSコーディングをする際につまづきがちなポイントについて紹介します。

line-heightについて

line-heightは行の高さを指定するCSSプロパティですが、このプロパティが忠実なコーディングをする際に厄介なポイントの一つです。PhotoshopやSketchなどのデザインツール上では、テキストオブジェクトは行の高さではなく行間を設定します。設定された行間をそのままCSSのline-heightに反映すると一行目と最終行で余計なpaddingが生まれてしまいます。そのため、前後のコンポーネントとのマージンをその分減らすなどの処置が必要です。

line_height_sample.html

<section>
  <h2>見出し1</h2>
  <p>段落1です。</p>
</section>
<section>
  <h2>見出し2</h2>
  <p>段落2です。</p>
</section>

line_height_sample.sass

section
  margin-bottom: 60px

h2
  $font-size: 16px
  $line-height: 20px
  $diff: ($line-height - $font-size) / 2
  font-size: $font-size
  line-height: $line-height
  margin: -$diff 0 (20px - $diff)

inline-blockのリストについて

リストの要素をinline-blockを使って横並びにした際に、意図しない空白が生まれてしまうことがあります。

inline_block_sample.html

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

inline_block_sampe.sass

li
  display: inline-block

このようにマークアップした場合に、リスト要素の間の空白が空白文字としてブラウザ側で表示されますが、本番配信時にはHTMLファイルはminifyされた状態で配信されるので、その空白の分だけ表示がずれてしまいます。 これを防ぐには開発環境でもminifyを行うか、ulに対してfont-size: 0を指定することで解決できます。 iQONではSlimを使っているので、Railsの開発環境設定に以下のように記述を追加して、minifyを行っています。

config/environments/development.rb

Iqon::Application.configure do
  # ... settings

  Slim::Engine.set_options pretty: false
end

モダンブラウザであればdisplay: flexを使って横並びにするのもよいと思います。

まとめ

今回は、どのようにしてデザインデータに忠実なCSSコーディングを行っているかを紹介しました。綺麗なサイトを保つためには、エンジニアとデザイナー双方の協力が不可欠です。それを踏まえた上で、ツールやテクニックを利用しお互いの負担が軽くなるようにできればと思い、日々コードを書いています。本記事が、精密なCSSコーディングができなくて困っている方の助けになれば嬉しいです。

最後に

VASILYでは、細部までこだわったサービスを一緒に作っていける仲間を募集しています。少しでもご興味のある方は以下のリンク先をご確認ください。 www.wantedly.com