UIデザイン手法: Atomic Designとは

#はじめに
今回はReact開発でAtomic Designについて学習したので、その内容をアウトプットとしてまとめたいと思います。間違い、ご指摘があればお願い致します。

#Atomic Designとは
現在のwebを閲覧する環境は多様化し、ブラウザの種類やUIも多くなり、開発の難易度が上がっています。Atomic Designはこうしたweb制作における構築や保守を支えてくれる設計で、その由来は化学の原理をヒントに考えられました。例えば、自然界では原子と原子が結びついて分子となり、分子と分子が結合して新たな物質を生み出します。
この理論を応用して多様化するweb開発環境でも堅牢で高品質なUIを一貫性を保ちつつ提供することができます。

#Atomic Designの基本概念
従来：ページ単位でコンプを作成
Atomic Design: 「**大枠**」(ページ)と「**部品**」（コンポーネント）の２つ分けてUIを捉える

Atomic Designはいくつかのコンポーネントを組み合わせることで、様々なインターフェイスやテンプレートを構築する方法論です。Reactと似ている構成方法ですが、デザインでも同じ考え方が有効です。

###コンポーネント利用のメリット
コンポーネントを利用する最大のメリットは**再利用性**です。
例えば、検索ボックスの「検索」のボタンはWebサイト内のあらゆるボタンに再利用することが可能です。コンポーネントの活用することは、効率や一貫性に大きく関わり、ユーザーがプロダクトを便利に使用するには欠かせないポイントです。

###コンポーネントの活用方法
コンポーネントを活用するには、ページとコンポーネントに分け、それらをさらに下記の単位に振り分けます。

- Atoms（原子）
- Molecules（分子）
- Organisms（有機物）
- Templates（テンプレート）
- Pages（ページ）

##Atoms
Atoms（原子）は、UIを構成する単位として最小のものです。
例えば、検索フォームで説明すると、

- 見出し（検索）
- 検索ボックス（入力フォーム）
- 送信ボタン

この３つそれぞれがAtomsです。
入力フォームだけでは何を入力すべきかは分かりません。また、ボタンを押しただけでも何が起こるかは分かりません。これらはAtomsの抽象的要素であり、複数が組み合わさって初めて機能的になるからだと言えます。

###Atomsの具体例

- ボタン
- 入力エリア
- 見出し
- アイコン
- チェックボックス
- ラジオボタン
- カラーパレット
- タイポグラフィー

##Molecules
Molecules（分子）はAtomsが複数組み合わさって成り立ちます。UIが意味を持ち、どのように使われるか具体性が表れます。ここで重要なポイントは**再利用性が保たれている**のかが1つのポイントです。
前項で検索フォームをAtomsの例として挙げましたが、その3つのAtomsが組み合わさったのが、Moleculesです。Moleculesになることで一連の流れが想像でき、より具体的なインターフェイスになります。

##Organisms
Organismsは、AtomsやMoleculesを組み合わさって作られます。必ずしもAtoms→Molecules→Organismsの順番である必要性はなく、Organismsが直接Atomsを参照することができます。これまでの構成要素に比べると複雑なUIになるため、再利用性はそこまで求められていません。

###Organismsの具体例

- Webサイトのヘッダー（検索フォーム[Molecules]、ロゴ[Atoms]、グローバルナビゲーション[Molecules]）
- webサイトのフッター
- ECサイトの商品一覧（商品一つ一つがMolecules）

##Templates
Templatesはワイヤーフレームと同様で、ページに表示する実データが反映される前の状態のことです。ページ構造やレイアウト構成などを説明するためのレイヤーです。

Templatesの特徴は、具体性のあるコンテンツが取り除かれているため、ページの「コンテンツ構造」に焦点を当てて、各コンポーネントがどのように表示されて、どのように動作するのかを確認できることです。コンポーネントには実際にコンテンツが流し込まれるため、**ページが持つ動的な要素の特性**を明確に理解することが重要です。

##Pages
Pagesは前項で説明をしたTemplatesに実際のデータを反映した状態です。一般的にはデザインコンプと呼ばれる状態を指します。PagesはTemplatesをインスタンス化した状態とも言えます。

Pagesでは**実際にデータを入れた状態で正しく表示されるか**を評価します。
例えば、価格が100円の表示が問題がなくとも、1000000円では表示は崩れてしまうのであればコンポーネントとしてダメです。

#Atomic Designのメリット
Atomic Designのメリットを語る前にまずは従来のデザインシステムについて解説します。

###デザインシステムとは
これまでのデザインを体系的にまとめる手段としてスタイルガイドを作成して全体の体裁を統一する手法がありました。デザインシステムはこれを発展させて、**抽象的なガイドラインから実際に使用可能なコンポーネントライブラリ**、さらには**コンポーネントをどのような環境で使うか**、**どのような基礎設計やコンテンツ原則に基づくか**などの上位概念まで取り持つことになります。
つまり、コンテンツのデザインを綺麗にしたり、効率化をするだけでなく、**どうすれば実際のプロダクトとして最終的に完成させられるか**までを考える必要がある。

このデザインシステムを実現するためには、コードレベルでの設計手法も非常に重要です。
Atomic Designのようなシステムチックなデザイン手法は、デザインシステムを非常にマッチします。

###開発におけるデザインの基準
1つのWebページに含まれるコンポーネントを決められた単位に分割することは、開発チームの中に1つの基準が生まれることになります。チーム内で統一した概念を持つことは開発工程において非常に重要です。

####構造的な考え方
Atomic Designには「動的に変化する要素」と「流し込まれるコンテンツ」の構造的な考え方があります。関数と引数に例えられる関係性で、UIから具体的なコンテンツを取り除いた状態状態として認識可能にします。特にコーディングスタイルのガイドラインとして有用で、データを物理的にどう処理するかを定める指針としても、設計に関与する考え方です。
例えば、UIからコンテンツのみを分離できる構造を理解していれば、コンテンツマーケターはデザイナーやエンジニアが設計したものを破壊する恐れもなく、コンテンツの配信が可能です。

####チーム開発に向けた応用
複数人でUIデザインを実践する場合、Atomic Designはコミュニケーションを助けるキーワードとなる。
「この要素はAtomsであるから、このように構築しよう」、「Organismsに相当するあのUIは、こんな構造になっているはずだ」など
チーム開発における「基準」としてあることがAtomic Designの１番の存在意義であり、何がAtomsで何がMoleculesであるかはさほど重要ではありません。(個人的な考え)

#コンポーネント開発のUIデザイン
Atomic Designは開発を効率化させますが、実際のUIデザインにも影響を与えます。
「スタイリング」「レイアウト」「トーン&マナー」の3つの視点からどのような変化を与えるのか説明します。

##スタイリング
コンポーネントを作る上で大切なのは、再利用性です。どこで利用されたとしても不変である必ず存在します。
例えば、赤色のボタンはどこで使用されても、赤色である必要があるため、コンポーネントが持つべき情報と言えます。
コンポーネントは様々な状態変化を含め動きのあるUIです。そのため、スタイリングを検討する際に最も重要なことは**変化に耐えられること**です。つまり、コンポーネントが持つ固有の情報と、コンポーネントが使われる時に発生する可変の情報に分ける必要があります。レスポンシブデザインの実装では横幅が可変になる実装が推奨されていた通り、コンポーネントがどこで描画されても、その状況に合致した見た目に変化させることが再利用性を担保するためには重要なポイントです。

```
ボタン幅を固定幅から可変にする例

Before: 120pxを超えるコンテンツが入った場合に崩れる恐れがある
.button {
    width: 120px;
}

After: 内容によって柔軟に幅が変化するようにしておく
.button {
    width: auto;
}
```

```
ダイアログ内のコンテンツがはみ出た場合における挙動の実装例

Before: 無闇にoverflow: hidden;を使ってしまうとコンテンツが見えなくなる可能性がある
.dialog {
    height: 300px;
    overflow: hidden;
}

After: はみ出たコンテンツをどう扱うかはよく考えておく
.dialog {
    height: 300px;
    overflow: scroll;
}
```

Atomic Designでは抽象度の高いAtomsやMoleculesから実際にデータを流し込むPagesを作ります。そこでは、最初に想定しているものとは異なる値が入力される可能性が考えられるため固定値を指定することが推奨されません。上記のコード以外にも、position: absolute;など固定的に指定するプロパティがCSSにはあります。コンポーネントを使用するシチュエーションを想像して、柔軟な挙動のUIを作りましょう。

##レイアウト
レイアウトで重要なポイントは**コンポーネント自身にレイアウト情報を持たせない**ことです。レイアウトに固有のプロパティを持たせてしまうと、再利用性が低下します。CSSには、自身のスタイリングに関するものと、レイアウトに関するものに大別されますが、CSSを学習する上でこの違いを区別して追加分けることができれば、コンポーネントベースの実装も十分に理解することができます。

```

.component {
    margin-right: 30px; /余白を持たせると再利用性が落ちる
}
```
シンプルな解決方法はラッパー要素の使用です。正しく配置するためにラッパーでコンポーネントを包み、そこにレイアウトを与えます。こうすることで、コンポーネントそのものはシンプルに保ったまま自由に置き換えできます。OOCSSのアプローチに近い手法で、コンポーネントが持つモジュール的な特養を活かせます。

```
<div class="layout">
  <Component />
</div>
```

```
.layout {
    margin-right: 30px;
}
```

MoleculesやOrganismsなどの複数の部品を組み合わせて作成する要素に関しても同じです。
子コンポーネントを含む場合、その内部的なレイアウト情報はその要素自身からはスタイリングと捉えることができ、CSSの特徴であるカスケーディングを利用することで柔軟に配置できます。この手法は、Atomic Designベースに設計されている「APBCSS」でのアプローチでもあります。

```
<-- buttonコンポーネント(Atoms) -->
<div class="button">...</div>

<-- userコンポーネント(Atomsを含んでいるMolecules) -->
<div class="user">
  <Button />
</div>
```

```
.user .button {
    margin-right: 30px; /Moleculesのスタイリングとして.Atomsのレイアウト指定している
}
```

##Flexbox
display: flex;と定義した要素はflexboxコンテナとして振る舞います。そして、flexboxコンテナの子要素は、特にCSSで指定せずとも自動的にflexboxアイテムとして振る舞います。この特性を利用することで、親要素の指定のみで各コンポーネントのレイアウトを可能にします。主に、Organismsにおいて、特定のエリア内にコンポーネントを配置する時に有効です。

```
<div class="layout">
  <Component />
</div>
```

```
.layout {
    width: 300px;
    height: 300px;

    /親要素をflexboxコンテナにする/
    display: flex;

    /flexboxアイテムのレイアウトを親要素から指定する/
    align-items: center;
    justify-content: center;
}
```

##トーン&マナー
Atomic Designの大きなメリットの１つとして全ての要素を俯瞰的に眺めることができることです。「どれだけの種類のUIが存在するのか」「それぞれのUIはどういった外観なのか」など
共通の基準を持たせた上で、それにそったUIを簡単に一覧にできるので、UI間の比較よりも正確に実施できます。
特に、企業組織では、会社や製品のブランド価値を高めるために、ブランドのアイデンティティの一貫性が重要視されるケースがあります。Atomic DesignのAtomsなどに該当するキーカラーやキーフォントなどは、トーン＆マナーのようなビジュアル表現ルールを決める際の重要な要素となります。

#Reactとの相性
Atomic DesignとReactは密接な関係性があります。

##肥大化しないコンポーネント
コンポーネントを作成する中で、様々な役割を１つのコンポーネントに詰め込んでしまうことがあります。これでは、可読性やメンテナンスの低下を引き起こし、結果的に設計の破綻に繋がります。このアンチパターンを回避するにはAtomic Designで設計することで回避できます。さらに役割分担が明確であることは、最適化も簡単になります。

##拡張性
Reactはライブラリとしての拡張性のためにも、コンポーネント単位をベースとして組み立てる手法を推奨しています。

(例)
Atoms...長方形ブロック、円柱ブロック(ブロックそのもの)
Molecules...ジェットバック、コックピット(ブロックで作った、換装可能な部品)
Organisms...飛行機
Templates...いろいろな飛行機が備わっている飛行場
Pages...XXX空港(具体的な名称の飛行機)

Reactでは、コンポーネントを親子関係の構図に読み込むことができ、Propsを使ってコンテンツの分離させることも可能です。Reactが持つライブラリとしての柔軟性と、Atomic Designが持つレイヤー構造の拡張性が合わさることで、強力なコンポーネント実装が実現でき、相互の利点を最大限に活かすことが可能です。

#参考
React開発　現場の教科書（株式会社マイナビ出版）
[Atomic Designを分かったつもりになる](https://design.dena.com/design/atomic-design-%E3%82%92%E5%88%86%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%A4%E3%82%82%E3%82%8A%E3%81%AB%E3%81%AA%E3%82%8B)