Adobe XDとBootstrapで作業を効率化 第3回: デザイントークンでつなぐAdobe XDとBootstrap

連載

Adobe XDとBootstrapで作業を効率化

前回の記事では、Adobe XDを使ってデザインガイドを作成し、登録したカラーやコンポーネントには「デザイントークン」として名前を付けました。今回は、デザイントークンを使って、デザインガイドとBootstrapを連携させる方法を紹介します。

連携方法はシンプルです。ただ、Bootstrapの構成を理解をしていないことには始まりません。最初に、連携方法を理解するのに必要なBootstrapの基本を説明しておきます。

Bootstrapの基本構成

Bootstrapは、CSSメタ言語であるSCSSを用いて管理されています(2020年1月時点)。SCSSは、少ない修正で多くの箇所の変更ができるシステムを構築できます。BootstrapもCSSの記述量は膨大ですが、SCSSを修正すれば簡単に様々な箇所の変更が行えるようになっています。この記事も、紹介する実例はSCSSの修正によるBootstrapのカスタマイズです。

SCSSからCSSの変換の仕方は、本記事では触れません。まだSCSSを触ったことのない方は、過去にDreamweaverを使った方法を紹介しているので参考にしてください。Dreamweaverを使えば、面倒な環境設定をしなくてもSCSSを利用することができます。

Dreamweaverで覚える最新Web開発ワークフロー: Sass編 \- Adobe Blog

それでは、Bootstrapの公式サイトからダウンロードできるソースファイルの構造を見てみましょう。主なフォルダ構成は下記のようになっています。

bootstrap/
├── dist/ # メタ言語から出力されたCSSやJSファイル
├── js/ # JSファイル
├── scss/ # SCSSメタ言語
│ ...
│ ...
└── site/ # Bootstrap公式サイトのファイル

これ以外にも様々なファイルがありますが、今回必要なのはSCSSフォルダの下にあるファイルのみです。

BootstrapのSCSSフォルダの中身

SCSSフォルダには以下のようなファイルが含まれています。

scss/
│ ## フォルダ
├── mixins/
├── utilities/
├── vendor/
│
│ ## ファイル
├── _alert.scss
├── _badge.scss
│ ...
├── _reboot.scss
├── _variables.scss
└── bootstrap.scss

これらのファイルは、システム的な役割を担うグループとコンポーネントのグループに分けて考えるとわかりやすいでしょう。mixinsやutilitiesは、グリッドのカラム数やボタンのクラス名の自動生成など、Bootstrapをシステム的に管理するために必要なファイルが含まれているフォルダです。

_alert.scssや_badge.scssといった、先頭に_(アンダースコア)の付いたファイルには、主にコンポーネントを構築するためのSCSSが記述されています。例外として、_reboot.scssにはリセットCSS、_variables.scssには変数と呼ばれるBootstrapの様々な箇所に影響を与える値が記述されています。

最後のbootstrap.scssは、コンポーネントの情報等が記述されたSCSSファイルを読み込んで、CSSとして出力するためのハブとなるファイルです。

BootstrapのSCSSの構成はbootstrap.scssをハブとして大きく2つに分けられる

Bootstrapの変数

前述のように_variables.scssは、コンポーネントの色やフォントサイズなどの情報が記述されているファイルです。下記のコードは、_variables.scssから、カラーとタイポグラフィの定義の一部を抜粋したものです。

// Color system
$blue: #007bff !default;
$indigo: #6610f2 !default;
$green: #28a745 !default;

$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;

// Typography

$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;

$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`
$font-size-lg: $font-size-base * 1.25 !default;
$font-size-sm: $font-size-base * .875 !default;

各行には、左側に$から始まる変数名、右側にその値が定義されています。例えば$primary変数の値は$blueです。その上にある行では、$blue変数の値として#007bffが定義されています。$primaryはBootstrapのprimaryボタンに使われている色です。そのため、$primary変数あるいは$blueの値を変えることで、primaryボタンの色を変更することができます。

デザイントークンでカラーを連携させる

今回の連載で紹介してきたように、BootstrapのUIキットをベースにデザインガイドを作成すると、デザイントークンの連携が簡単になります。フレームワークが提供している要素をそのままデザインガイドの一部として利用すると、コード側にはそれに対応する変数が既に宣言されているからです。

例えば、第2回では、XDのアセットパネルに登録したボタンの色に「Primary」や「Success」などの名前を付けましたが、これらのデザイントークンは_variables.scssの中に記述されているため、新規追加する必要がありません。

従って、行うべき作業は、Bootstrap側の$primaryの値として、デザインガイドで「primary」というデザイントークンが付けられている色を指定するだけです。

デザイントークンと変数の関係性

ここで、デザイントークンを共通言語とするAdobe XDとBootstrapのカラーの連携手順を、箇条書きでおさらいしてみましょう。

  1. XDでUI Kitを使用して必要なカラーパレットを作成
  2. カラーパレットの個々の色にデザイントークンを付加
  3. _variable.scssのデザイントークンに対応する変数にデザインガイドで指定された値を指定

このようにシンプルな手順で、とても簡単にデザインガイドに指定されているカラーを用意できます。とはいえ、あまりBootstrapっぽくない色使いの場合もあるでしょう。そこで、参考としてTOYOTA SHAREの事例を紹介しておきます。このサイトもデザインシステムLiteのデザインをXDで作成し、Bootstrapを用いてコンポーネントを構築しています。

「トヨタの新しいカーシェアサービス TOYOTA SHARE」のキャプチャー

このサイトのカラーパレットはブランドカラーの赤をキーカラーとして構築されていて、赤のバリエーションが3つと、グレースケールの色が複数定義されています。色それぞれに役割を明確にしていることがこのデザインガイドのポイントです。このように色の役割を明確にすると、より強力なコミュニケーションツールとして使えます。

赤系統をキーカラーとして、グレイスケールで構築している

この事例では「TOYOTA SHARE Red」「Light Variant – TOYOTA SHARE Red」「Dark Variant – TOYOTA SHARE Red」などがデザイントークンとして使われています。色のバリエーションに対応するために下のようなコードを使ってデザイントークンを連携させています。

// Color system
$red: #EB0A1D;
$light-red: #EA5849;
$dark-red: #BF0000;

$primary: $red;

デザイントークンでフォントを連携させる

次はフォント連携の例を紹介します。これもTOYOTA SHAREの事例からです。

TOYOTA SHAREの事例におけるデザインシステムLiteのタイポグラフィは以下の画像の通りに定義されています。和文と欧文でフォントファミリーを変えるデザインになっていて、デスクトップ用とモバイル用に異なるスタイルが指定されています。

タイポグラフィのデザインシステム

この場合、デザイントークンをデスクトップ用には「h1-desktop」、モバイル用には「h1-mobile」のように別々に定義することもできますが、この事例では作業量を減らすために「h1」にまとめています。

そうすると、画面サイズにあわせてタイポグラフィのスタイルを切り替える必要がありますが、Bootstrapはこれに対応していません。そこで、SCSSを使って、タイポグラフィのデザイントークンの管理とブレークポイントへの対応を行う仕組みをつくりました。下のコードはその一部の抜粋です。

まず、map型を使って、通常時の画面サイズ(default)と、特定のブレークポイントより画面が小さい場合(md)のfont-sizeline-heightの値を記述します。

$type-map: (
  h1: (
    default: (
      font-size: 40px, line-height: 1.3
    ),
    md: (
      font-size: 30px, line-height: 1.35
    )
  ),
  h2: (
    default: (
      font-size: 32px, line-height: 1.35
    ),
    md: (
      font-size: 24px, line-height: 1.5
    )
  ),

次は、設定したタイポグラフィのマップを、CSSに出力するコードです。これはMixinで用意しました。

@mixin get-type($prefix: '') {
  @each $select, $get-map in $type-map {
    #{$prefix}#{$select} {
      @each $media, $propaties in $get-map {
        @if($media == 'default') {
          @each $propaty, $value in $propaties {
            #{$propaty}: #{$value};
          }
        } @else {
          @include media-breakpoint-down($media) {
            @each $propaty, $value in $propaties {
              #{$propaty}: #{$value};
            } 
          }
        }
      }
    }
  }
}

上記のMixinを@include get-type('.u-type-');で呼び出すと、自動的に要素にフォントサイズなどが指定され、ブレークポイントにおけるCSSのルールセットも出力されます。
下記がCSSの出力例です。(メディアクエリーはPostCSSのプラグインを使ってまとめています)

.u-type-h1{font-size:40px;line-height:1.3}.u-type-h2{font-size:32px;line-height:1.35}.u-type-h3{font-size:28px;line-height:1.4}.u-type-h4{font-size:24px;line-height:1.5}.u-type-h5{font-size:20px;line-height:1.5}.u-type-h6{font-size:16px;line-height:1.6}.u-type-p{font-size:16px;line-height:1.8}.u-type-small{font-size:14px;line-height:1.6}

@media (max-width: 992.98px){
  .u-type-h1{font-size:30px;line-height:1.35}.u-type-h2{font-size:24px;line-height:1.5}.u-type-h3{font-size:22px;line-height:1.5}.u-type-h4{font-size:20px;line-height:1.5}.u-type-h5{font-size:16px;line-height:1.6}.u-type-h6{font-size:14px;line-height:1.6}.u-type-p{font-size:14px;line-height:1.8}.u-type-small{font-size:12px;line-height:1.6}
}

この方法であれば、異なる画面サイズに対するタイポグラフィの定義を一覧性よく管理できます。CSSで記述した場合、メディアクエリーによって2つの定義が離れた位置に記述されることになるため、管理のことを考えると上手な方法とはいえません。

デザイントークンでボタンを連携させる

さて、最後の基本要素であるボタンもデザイントークンを使って連携させましょう。ボタンコンポーネントには、色だけでなく余白や角丸の大きさなどいくつものスタイルを指定できます。デザインシステムLiteに定義されるボタンには、様々な見た目のボタンが存在することになるでしょう。

ボタンのカスタマイズ例

デザインシステムLiteでは、デザイントークンとして指定されたボタンのスタイルを効率よく実現することが重要です。この記事では、デザインシステムLiteの2つの実例から、ボタンのスタイル修正に関する効率化のポイントをいくつかご紹介します。

Adobe Max Japan 2019サイトの例

下の図は第2回の記事でお見せしたAdobe Max Japan 2019のデザインシステムLiteのボタンです。ボタンの色と角丸の大きさが変更されていますが、それ以外のスタイルは変わっていません。各ボタンには、Bootstrapの変数で管理できるようにデザイントークンが付けられています。

デザインシステムLiteの修正版。primaryボタンが青になっている

デザイン通りの見た目になるように、Bootstrapの関連する変数を、下記のように変更しています。

// ボタンの色
$primary: #1b8be2; // デフォルトから変更
$secondary: #6C757D;
$success: #28a745;
$info: #17a2b8;
$warning: #FF7C00; // デフォルトから変更
$danger: #dc3545 ;
$light: #FFF; // デフォルトから変更
$dark: #343A40; // デフォルトから変更

// 角丸
$btn-border-radius: 1.25rem;
$btn-border-radius-lg: 1.5rem;
$btn-border-radius-sm: 1rem;

ここまでは簡単ですね。ただ、この事例では、変数を修正しただけでは指定通りに構築できないスタイルがありました。それは、ホバー時とアクティブ時の背景色です。デザインガイドでは、背景色は不透明度が30%変化すると指定されています。

Bootstrapのデフォルトでは背景色が暗くなるが、不透明度で変化させたい

Bootstrapでは、ボタンの色からホバー時とアクティブ時の背景色が自動的に生成されます。下記はBootstrapのボタン生成のMixinの一部の抜粋です。

@mixin button-variant(
  $background,
  $border,
  $color: color-yiq($background),
  $hover-background: darken($background, 7.5%),
  $hover-border: darken($border, 10%),
  $hover-color: color-yiq($hover-background),
  $active-background: darken($background, 10%),
  $active-border: darken($border, 12.5%),
  $active-color: color-yiq($active-background)
) {
  color: $color;
  @include gradient-bg($background);
  border-color: $border;
  @include box-shadow($btn-box-shadow);

  &:hover {
    color: $hover-color;
    @include gradient-bg($hover-background);
    border-color: $hover-border;
  }
}

コードの2行目の$backgroundは、$primaryなどのボタンの色の変数が入ります。コードの4行目の$color: color-yiq($background)は文字色を判別していて、$backgroundが濃い色であれば「白(#FFF)」を、 薄い色であれば「黒(#000)」を出力します。

そしてコードの5行目がホバー時の背景色を生成しています。$hover-background: darken($background, 7.5%)は、パーセントで指定された分だけ色の輝度を下げる関数ですす。

Bootstrapでは、これらのコードによって、ボタンに1つの色を指定しただけでボタンのスタイルが自動的に生成される仕組みになっています。便利な機能ですが、背景色を思い通りにするには、このコードを書き替える必要があります。下記が修正したコードです

@mixin button-variant(
  $background,
  $border,
  $hover-background: rgba($background, 0.7),
  $hover-border: rgba($background, 0),
  $active-background: rgba($background, 0.7),
  $active-border: rgba($background, 0)
) {
  color: color-yiq($background);
  @include gradient-bg($background);
  border-color: $border;
  @include box-shadow($btn-box-shadow);
  border-width: 2px;

  @include hover {
    color: color-yiq($hover-background);
    @include gradient-bg($hover-background);
    border-color: $hover-border;
  }
}

$hover-background変数と$active-background変数には、rgba()関数を使って不透明度が70%になるよう指定しています。また、ホバー時の文字色にはcolor-yiq()関数を利用して、背景色とのコントラストを保つようにしています。

このように、ボタンのスタイルには、変数に値を指定するだけでは実現できず、コードの修正が必要になるものもあります。他の人とコードを共有する場合は、どこで不透明度が指定されているかを理解しやすいように、不透明度を変数(デザイントークン)として宣言するなどの工夫を考慮しても良いかもしれません。

TOYOTA SHAREのサイトの例

もうひとつTOYOTA SHAREの事例を紹介します。このサイトのデザインガイドでは、ボタンのサイズごとにフォントサイズや余白が細かく指定されていました。そのため、ボタンサイズごとにスタイル指定を効率よく行う必要がありました。

ボタンのサイズによってフォントサイズや余白が指定されている

上記の指定を行うため、button-sizeミックスインを使用して、クラスごとの指定を記述しました。このミックスインは、第1引数は上下の余白、第2引数は左右の余白、第3引数はフォントサイズを指定できます。下記のように、Bootstrapの既存コードを上書きしています。

.btn {
  @include button-size(
    0.56em,  // 上下余白
    1.4em,   // 左右余白
    16px,    // フォントサイズ
    1,       // line-height
    999em    // 角丸の大きさ
 );
}

.btn-xl {
  @include button-size(0.5em, 1.5em, 24px, 1, 999em);
}

.btn-lg {
  @include button-size(0.5em, 1.5em, 20px, 1, 999em);
}

.btn-sm {
  @include button-size(0.29em, 1.3em, 14px, 1, 999em);
}

.btn-xs {
  @include button-size(0.21em, 1em, 14px, 1, 999em);
}

なお、ボタンの角丸の大きさに「999em」を指定していますが、これはCSSのテクニックで、横幅と縦幅のどちらかを狭い方を基準に丸くできます。

その他のコンポーネントを連携させる

最後に基本要素以外のコンポーネントの例も紹介しておきましょう。Adobe Max Japan 2019のサイトでは、グリッドの最大幅とガター(ボックスとボックスの間の間隔)の変数を変更しています。下がデザインシステムLiteのデザインです。

デスクトップとタブレット、スマートフォンの最大幅などが指定されている

変更したBootstrapの変数は以下の通りです。

container-max-widths: (
  sm: 768px, // デフォルトから変更
  md: calc(1024px - 4rem), // デフォルトから変更
  lg: calc(1200px - 4rem), // デフォルトから変更
  xl: 1200px // デフォルトから変更
);

$grid-columns: 12;
$grid-gutter-width: 2rem; // デフォルトから変更

TOYOTA SHAREのデザインシステムでは、ヘッダーとフッターのコンポーネントが定義されています。ヘッダーもフッターも表示幅に応じて段階的に見た目が変わります。

ヘッダーとフッターのコンポーネント

CSSではBootstrapのMixinを使用してブレークポイントに合わせて指定を行なっています。

実際のSCSSコードは下記のようになっています。media-breakpoint-down()は、引数に指定された値を基準に画面幅が狭くなった時に適用され、media-breakpoint-up()は、引数に指定された値を基準に画面幅が広くなった時に適用されます。

.c-header-inner {
  display: flex;
  align-items: center;
  padding-left: 30px;
  @include media-breakpoint-down(md) {
  /* @media (max-width: 992.98px) に変換される */
    padding-left: 20px;
    border-bottom: 1px solid #E6E6E6;
  }
}
.c-header__logo-figure {
  @include media-breakpoint-up(lg) {
  /* @media (min-width: 993px) に変換される */
    width: 200px;
    height: 26px;
  }
  @include media-breakpoint-down(md) {
  /* @media (max-width: 992.98px) に変換される */
    width: 100px;
    height: 13px;
  }
}

デザインシステムと効率化

この連載では、デザインシステムのビジュアルコミュニケーションツールとしての有効性と、小規模なサイトや更新をあまり必要としない期間限定のサイトにおける、デザインシステムLiteの利点を説明しました。

デザインシステムLiteは、簡単に始められるデザインシステムです。そして、デザインと開発を円滑に進める鍵になるのはデザイントークンの使い方です。特に使用するCSSフレームワークに合わせることは重要です。もし、BootstrapのPrimaryボタンのデザイントークンを、「Primary」ではなくて「Main」とした場合、コミュニケーションは噛み合わなくなります。

デザインシステムのデザインガイドを構築するデザイナーはある程度、フレームワークの知識が必要になります。その際、フレームワークに対応したUIキットの使用は助けになるでしょう。開発側もデザインの知識を持って、デザインガイドを読み取る力は必要です。両者の協力が効率化の近道になるでしょう。