Chakra UI・ShadCN・Material UIを活用したデザインシステムの構築と運用

  • shadcn
    shadcn
  • materialui
    materialui
  • prettier
    prettier
  • tailwindcss
    tailwindcss
  • storybook
    storybook
  • react
    react
  • css
    css
2024/03/12に公開

はじめに

近年、デザインシステムの重要性が高まり、多くの企業やプロジェクトで導入が進んでいます。デザインと開発の一貫性を保ち、スケーラブルなUIを実現するためには、適切な設計と運用が不可欠です。

本記事では、デザインシステムを構築・運用するための具体的な手法を解説します。特に、Chakra UI・ShadCN・Material UI などのUIフレームワークを活用しながら、実際のプロジェクトで役立つ実践的なアプローチを紹介します。これからデザインシステムを導入しようと考えている方や、既存のシステムをより洗練させたい方にとって、有益な情報を提供できればと思います。

デザインシステムの要件定義と適用ガイドラインの作成

デザインシステムは、統一されたUI/UXを提供し、デザイナーとエンジニアのコラボレーションを円滑にするためのフレームワークです。要件定義と適用ガイドラインを策定することで、システムの一貫性と拡張性を確保できます。

デザインシステムとは?

デザインシステム(Design System)は、プロダクトのUI(ユーザーインターフェース)とUX(ユーザー体験)を統一し、開発・デザインの効率を向上させるための仕組みです。
一般的に、以下の要素を含みます:

  • UIコンポーネントライブラリ
    ボタン、フォーム、カード、モーダルなどの共通コンポーネント
  • スタイルガイド
    色、タイポグラフィ、間隔、アイコンの使用ルール
  • パターンライブラリ
    ナビゲーション、検索、フォームバリデーションなどのUXパターン
  • ブランドガイドライン
    ロゴ、トーン&マナー、アクセシビリティの基準
  • ドキュメンテーション
    デザイナーやエンジニアが参照できる適用ルール

デザインシステムの目的

「統一されたUI/UXを提供」とは、以下の課題を解決することを指します。

  • 一貫性のあるデザイン
    • プロダクト内で見た目や動作がバラバラにならない
    • 例えば、同じボタンでもページごとにデザインが異なる問題を防ぐ
  • 開発・デザインの効率化
    • すでに決められたコンポーネントを再利用できるため、作業の重複を防げる
    • デザイナーとエンジニア間のやりとりがスムーズになる(「このボタンのデザインどうする?」という議論を減らせる)
  • UXの向上
    • ユーザーが迷わずに操作できるように統一された体験を提供できる
    • 例えば、フォームのエラーメッセージが画面ごとに異なると、ユーザーは混乱する

誰が使用するか?

デザインシステムは、複数の職種が関与するため、それぞれの役割を明確にし、適用しやすい設計を行う必要があります。

  • デザイナー
    • UIデザインの一貫性を保つ
    • FigmaやSketchなどのデザインツールでコンポーネントを管理
    • ビジュアルやUXの改善を推進
  • フロントエンドエンジニア
    • React, Next.js, Vueなどのフレームワークでコンポーネントを実装
    • 再利用可能なUIコンポーネントを開発
    • スタイル設計(Tailwind CSS, Emotion, Material-UIなど)
  • プロダクトマネージャー
    • デザインシステムがプロダクト全体のビジョンと整合しているか確認
    • 仕様策定や導入計画のサポート

設計時の考慮点

  • チームのスキルセットに応じた導入(高スキルな開発チーム向け or 初心者にも適用しやすい設計)
  • 小規模チームでは、複雑な設計を避け、シンプルなルールを適用

どのプロジェクトに適用するか?

デザインシステムの適用範囲を明確にすることで、実用性を高めます。

  • 小規模プロジェクトでも活用可能か?
    • YES: シンプルなコンポーネントセットを提供し、開発効率を向上させる
    • NO: 大規模プロジェクトに特化し、小規模ではオーバーヘッドになる可能性あり
  • マルチプラットフォーム(Web, Mobile)で共通化可能か?
    • Web: React, Vueなどのフロントエンドフレームワーク
    • Mobile: React Native, Flutterなどで再利用できるか検討
  • 共通化のポイント
    • UIコンポーネントのデザイン言語を統一(Material Design, Fluent UI など)
    • モバイルとWebで使えるコンポーネントライブラリ(MUI, Chakra UI など)を活用

コアコンポーネントの定義

デザインシステムの中心となるコンポーネントを定義し、適用ルールを策定します。

  • ボタン(Button)

    • プライマリ、セカンダリ、アイコンボタンなどのバリエーション
    • サイズ(small, medium, large)
    • インタラクション(ホバー、フォーカス、クリック時のスタイル)
  • 入力フォーム(Input, Select, Checkbox, Radio)

    • バリデーションルールの統一(エラーメッセージの表示方法など)
    • デザインの統一(ボーダー、プレースホルダー、フォーカス時の挙動)
  • モーダル(Modal, Dialog)

    • 全画面モーダル / 部分モーダルの使い分け
    • 背景のオーバーレイ処理、アクセシビリティ対応(キーボードナビゲーション)
  • コンポーネントの適用ルール

    • コンポーネントの使用シーンを明確化(例:ボタンはCTAのみプライマリカラーを使用)
    • スタイルの統一(Tailwind CSSのカスタムクラス、CSS変数の活用)

ガイドラインの整備

デザインシステムを適切に運用するために、コンポーネントの管理・ドキュメント整備が必要です。

1. コンポーネントの命名規則

  • BEM(Block, Element, Modifier)
    • 例: .button--primary, .input__label
  • カスタム命名規則(Tailwind CSS, CSS Modules, Emotion など)
    • Tailwind: btn-primary, input-label
    • CSS Modules: styles.primaryButton

2. Figma / Storybook でのコンポーネント管理

  • Figma
    • デザインコンポーネントをライブラリ化
    • コンポーネントのバリアント(サイズ、色、状態)を定義
  • Storybook
    • フロントエンドエンジニア向けのコンポーネントカタログ
    • コンポーネントの挙動をドキュメント化(Propsの説明、インタラクションテスト)

3. ドキュメントの作成

  • Notion / Confluence などで情報共有
    • デザインシステムの基本方針、導入ガイドを明記
    • よくある質問(FAQ)を掲載し、スムーズな適用を支援
  • README / API ドキュメント
    • コンポーネントのProps一覧、使用例を掲載
    • カスタマイズ方法や拡張方法を記載

UI コンポーネントの設計と実装

UI コンポーネントの設計と実装において、Atomic Design の考え方を取り入れることで、開発のスケーラビリティとメンテナンス性が向上します。また、Next.js + Tailwind CSS + ShadCN を活用することで、モダンで洗練されたコンポーネントを効率よく作成できます。さらに、Storybook を使うことで、コンポーネントの可視化や管理が容易になり、デザイナーや開発者との連携もスムーズになります。

Atomic Design の活用

コンポーネント設計において、Atomic Design の概念を取り入れることで、管理しやすく、再利用性の高いコンポーネントを構築できます。

コンポーネントの分類

1. Atoms(原子)

  • UI の最小単位(例:ボタン、入力フィールド、アイコン)
  • 再利用性が高く、他のコンポーネントの構成要素になる
    import { cn } from "@/lib/utils";
    
    export const Button = ({ 
      children,
      className 
    }: { 
      children: React.ReactNode
      className?: string 
    }) => {
      return <button className={cn("px-4 py-2 rounded-md bg-blue-500 text-white", className)}
        >{children}
      </button>;
    };
    

2. Molecules(分子)

  • Atoms を組み合わせた小さな UI コンポーネント(例:検索バー、フォームグループ)
    import { Input } from "@/components/ui/input";
    import { Button } from "@/components/ui/button";
    
    export const SearchBar = () => {
      return (
        <div className="flex space-x-2">
          <Input type="text" placeholder="検索…" />
          <Button>検索</Button>
        </div>
      );
    };
    

3. Organisms(有機体)

  • Molecules や Atoms を組み合わせた、ページ内の大きな UI コンポーネント(例:ヘッダー、ナビゲーション)
    import { SearchBar } from "@/components/molecules/SearchBar";
    
    export const Header = () => {
      return (
        <header className="flex justify-between items-center p-4 bg-gray-800 text-white">
          <h1 className="text-lg font-bold">サイト名</h1>
          <SearchBar />
        </header>
      );
    };
    

4. Templates(テンプレート)

  • Organisms を配置し、ページレイアウトの基本構造を定義(例:2カラムレイアウト、ダッシュボードの枠組み)
    import { Header } from "@/components/organisms/Header";
    
    export const MainLayout = ({ 
      children 
    }: { 
      children: React.ReactNode 
    }) => {
      return (
        <div>
          <Header />
          <main className="p-4">{children}</main>
        </div>
      );
    };
    

5. Pages(ページ)

  • Templates に実際のデータやコンテンツを組み込んで画面を完成させる
    import { MainLayout } from "@/components/templates/MainLayout";
    
    const HomePage = () => {
      return (
        <MainLayout>
          <h2>ようこそ!</h2>
          <p>このサイトは Atomic Design を活用しています。</p>
        </MainLayout>
      );
    };
    
    export default HomePage;
    

Next.js + Tailwind CSS + ShadCN を使ったコンポーネント実装例

Next.js と Tailwind CSS を組み合わせることで、柔軟な UI 設計が可能 になり、ShadCN を活用することで モダンなデザインを簡単に実装 できます。

ShadCN UI のセットアップ

ShadCN を導入するには、以下のコマンドを実行します。

npx shadcn-ui@latest init

その後、必要なコンポーネントをインストールします。下記の例はボタンコンポーネントをインストールしています。

npx shadcn-ui@latest add button

実装例: プライマリボタン

import { Button } from "@/components/ui/button";

export const PrimaryButton = () => {
  return <Button variant="primary">クリック</Button>;
};

ShadCN を使うことで、カスタマイズ可能な Button コンポーネントを簡単に作成でき、統一されたデザイン を維持しながら開発を進められます。

Next.jsのプロジェクトにShadcnとTailwind CSSを導入し実際に画面を作成するチュートリアルを公開しています。合わせてご参考ください。

https://shinagawa-web.com/blogs/nextjs-tailwind-shadcn-homepage

Storybook を使ったコンポーネント管理

Storybook を導入すると、コンポーネントの可視化、デザイナーとのコラボレーション、UI のテストが容易 になります。
例えば、PrimaryButton コンポーネントを開発するとき、Storybook 上でバリエーション(色やサイズの違い)を確認しながら調整できます。

Storybook のセットアップ

npx storybook init

その後、stories フォルダ内にコンポーネントごとのストーリーファイルを作成します。

実装例: ボタンの Storybook

import type { Meta, StoryObj } from "@storybook/react";
import { PrimaryButton } from "@/components/ui/PrimaryButton";

const meta: Meta<typeof PrimaryButton> = {
  title: "Components/Button",
  component: PrimaryButton,
};

export default meta;

export const Default: StoryObj<typeof PrimaryButton> = {
  args: {},
};

このように設定すると、Storybook で 作成したPrimaryButton の動作を確認できます。


UI フレームワークの導入(Chakra UI / ShadCN / Material UI などの活用)

フロントエンド開発において、UI フレームワークの選定は、開発速度・保守性・デザインの一貫性に大きな影響を与えます。ここでは、代表的な UI フレームワークである Chakra UI、ShadCN、Material UI について詳しく解説し、どのようなプロジェクトに適しているかを比較します。

各フレームワークの特徴と比較

フレームワーク 特徴 カスタマイズ性 主な用途
Chakra UI 柔軟なスタイルシステムとコンポーネントライブラリを提供。デフォルトでアクセシビリティが考慮されている。 高い 小規模〜中規模プロジェクト
ShadCN Tailwind CSS ベースで軽量。デザイントークンを活用しながら最小限のスタイルで構築可能。 非常に高い Next.js を使ったプロジェクト向け
Material UI Google の Material Design を実装。企業向け SaaS などの大規模開発に適する。 高い 大規模プロジェクト、エンタープライズ向け

Chakra UI

  • 特徴
    • sx プロパティを用いた直感的なスタイル定義
    • コンポーネントベースで、アクセシビリティを考慮した UI
    • スタイルのテーマカスタマイズが容易
    • 公式コンポーネントが豊富で、開発速度を向上
  • メリット
    • @chakra-ui/react の導入だけで基本的なコンポーネントが揃う
    • デフォルトでレスポンシブデザインを考慮
    • theme のカスタマイズでデザインの一貫性を保ちやすい
  • デメリット
    • コンポーネントのスタイルが Chakra 独自のものになるため、自由度が低め
    • Tailwind のようなユーティリティファーストの設計には向かない

ShadCN

  • 特徴
    • Tailwind CSS ベース で構築され、クラスベースのスタイリングが可能
    • 必要なコンポーネントを コピー&ペースト して利用する方式(パッケージインストールではなく、コードをプロジェクトに直接組み込む)
    • ShadCN UI(shadcn/ui) は Radix UI を活用し、アクセシビリティを考慮したコンポーネントを提供
  • メリット
    • カスタマイズの自由度が非常に高い(Tailwind CSS を活かせる)
    • 不要なコンポーネントを削除でき、バンドルサイズを抑えられる
    • シンプルで拡張性が高い
  • デメリット
    • 他の UI フレームワークのような統一されたデザインシステムがない
    • Tailwind CSS に慣れていないと学習コストが高い
    • コンポーネントのメンテナンスは自己責任

Material UI

  • 特徴
    • Google の Material Design を忠実に再現
    • 企業向けの SaaS 開発やエンタープライズアプリケーションでの採用が多い
    • @mui/system を活用し、CSS-in-JS のスタイリングも可能
    • MUI X を利用すれば、高度なテーブルやデータグリッドの機能も利用可能
  • メリット
    • デザインガイドラインが明確 で統一感のある UI を作りやすい
    • 豊富なコンポーネント群で、開発工数を大幅に削減
    • MUI X により、高度な UI 要件にも対応可能
  • デメリット
    • デフォルトのデザインが Material Design に強く依存 するため、カスタマイズがやや面倒
    • コンポーネントが多機能な分、バンドルサイズが大きくなりがち

プロジェクトに適した UI フレームワークの選び方

選定基準

要件 おすすめの UI フレームワーク
開発速度を重視(直感的なスタイリング) Chakra UI
Tailwind CSS を最大限活用 ShadCN
企業向け SaaS / 大規模開発 Material UI
バンドルサイズを小さくしたい ShadCN
アクセシビリティを重視 Chakra UI / Material UI
Google の Material Design を採用 Material UI

具体的な適用シナリオ

  • 小〜中規模のアプリで、デフォルトのデザインでも十分な場合
    • Chakra UI を選択
    • 例: ToDo アプリ、個人開発のプロジェクト
  • Next.js を活用し、自由度の高いカスタマイズを行いたい場合
    • ShadCN を選択
    • 例: スタートアップ向けの SaaS、シンプルなダッシュボード
  • 企業向けの SaaS やエンタープライズ向けのシステム
    • Material UI を選択
    • 例: 管理システム、業務アプリ

レスポンシブデザイン対応の強化

スマートフォンやタブレットの普及により、レスポンシブデザインの重要性がますます高まっています。ユーザーがどのデバイスからアクセスしても快適に閲覧できるようにすることは、Web開発において必須の要素です。本記事では、レスポンシブデザイン対応を強化するためのポイントや実践的な手法について解説します。

ブレイクポイントの適切な設定

レスポンシブデザインを実現するためには、適切なブレイクポイントを設定することが重要です。一般的なブレイクポイントの例を以下に示します。

  • 480px 以下: スマートフォン
  • 768px 以下: タブレット
  • 1024px 以下: 小型デスクトップ
  • 1200px 以上: 大型デスクトップ

CSSの @media ルールを活用し、適切なスタイルを適用しましょう。

@media (max-width: 768px) {
  .container {
    flex-direction: column; /* 画面幅が768px以下のときに、レイアウトを縦方向に変更 */
  }
}

フレキシブルなレイアウト設計

固定幅のレイアウトではなく、flexboxgrid を活用してフレキシブルなレイアウトを設計することで、さまざまな画面サイズに対応できます。

Flexboxを使用したレスポンシブ対応

.container {
  display: flex;
  flex-wrap: wrap;
}
.item {
  flex: 1 1 50%;
}
@media (max-width: 768px) {
  .item {
    flex: 1 1 100%;
  }
}
  • 子要素を折り返し可能にする
  • 各要素の幅を50%に設定
  • 画面幅が768px以下のときに、要素を1列に変更

CSS Gridを使用したレスポンシブ対応

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}
  • 200px以上のカラムを作成し、幅に応じて調整
  • 要素間の間隔を16px設定

画像の最適化

画像のサイズが固定されていると、小さな画面でレイアウトが崩れることがあります。max-width: 100% を使用し、コンテンツ幅に応じて縮小するように設定しましょう。

img {
  max-width: 100%;
  height: auto;
}
  • 画像の幅を親要素の最大幅に合わせる
  • アスペクト比を維持

また、srcset を活用することで、適切なサイズの画像を提供できます。

<img src="small.jpg" srcset="medium.jpg 768w, large.jpg 1200w" alt="レスポンシブ画像">

このコードは、画面幅に応じて medium.jpglarge.jpg を適用し、最適な画像サイズを提供します。

フォントサイズの調整

デバイスごとに適切なフォントサイズを適用することで、可読性を向上させます。remvw を活用するのが推奨されます。

body {
  font-size: 16px; /* デフォルトのフォントサイズ */
}
@media (max-width: 768px) {
  body {
    font-size: 14px; /* 画面幅が768px以下のときにフォントサイズを小さくする */
  }
}

5. ナビゲーションの最適化

小さな画面では、ハンバーガーメニューのようなナビゲーションを採用することで、使いやすさを向上させられます。

<button class="menu-toggle"></button>
<nav class="nav-menu">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
.nav-menu {
  display: none;
}
.menu-toggle {
  display: block;
}
@media (min-width: 768px) {
  .nav-menu {
    display: block;
  }
  .menu-toggle {
    display: none;
  }
}
  • 初期状態ではメニューを非表示
  • モバイル向けにボタンを表示
  • 画面幅が768px以上のときにメニューを表示
  • メニューボタンを非表示にする

6. ビューポートメタタグの設定

レスポンシブデザインを適用するために、HTMLの <head> 内に適切なビューポートメタタグを設定しましょう。

<meta name="viewport" content="width=device-width, initial-scale=1">

このタグを設定することで、デバイスの幅に応じたスケール調整が適用され、レスポンシブデザインが適切に機能するようになります。

デザインの一貫性を高めるためのカラーパレット・タイポグラフィ・スペーシングの統一

ウェブやアプリのデザインにおいて、一貫性のあるビジュアルはユーザー体験を向上させ、ブランドの認識を強化します。そのために重要なのが、カラーパレット、タイポグラフィ、スペーシングの統一です。それぞれの要素をどのように設計し、実践するべきかを解説します。

カラーパレットの統一

ベースカラーの選定

カラーパレットは、ブランドやサービスの印象を決定づける重要な要素です。まず、以下の基本カラーを決めましょう。

  • プライマリーカラー(ブランドの主色)
  • セカンダリーカラー(補助的なカラー)
  • アクセントカラー(強調したい箇所に使うカラー)
  • ニュートラルカラー(背景やテキスト用)

カラーのバリエーション

色のバリエーションを統一するために、明度や彩度を調整したバージョンを用意し、以下のような用途で活用します。

  • ライトバージョン(背景用)
  • ミディアムバージョン(ボタンやUI要素)
  • ダークバージョン(テキストやシャドウ)

色のコントラストを意識する

視認性を確保するために、WCAG(Web Content Accessibility Guidelines)の基準を満たすコントラスト比を意識しましょう。

  • 通常のテキスト: 4.5:1以上
  • 大きなテキスト(18px以上): 3:1以上

カラースタイルを定義

デザインツール(Figma, Adobe XDなど)やCSS変数、Tailwind CSSのカスタムテーマを利用して、統一されたカラースタイルを管理しましょう。

:root {
  --primary-color: #1E90FF;
  --secondary-color: #FFD700;
  --neutral-color: #F5F5F5;
}

タイポグラフィの統一

フォントの選定

フォントはブランドの個性を表現する重要な要素です。選定時のポイントは以下の通りです。

  • 見出し用フォント(太めで視認性が高い)
  • 本文用フォント(可読性が高く、読みやすい)
  • モノスペースフォント(コードや数字を扱う場合に使用)

例:

body {
  font-family: 'Inter', sans-serif;
}
h1, h2, h3 {
  font-family: 'Poppins', sans-serif;
}

フォントサイズと階層の設定

一貫性のあるテキストのサイズを決めるため、スケールを設定します。

h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.75rem; }
p { font-size: 1rem; }

モジュラースケール

モジュラースケール(Modular Scale)は、デザインにおけるフォントサイズやスペーシングの比率を統一するための手法です。単純な「倍数」ではなく、数学的な比率(例えば 1.25, 1.414, 1.618 など)を基準にしてサイズを決定することで、バランスの取れた視覚的な階層を作れます。

例えば、比率 1.414(白銀比) を基にフォントサイズを決める場合、基準サイズを 16px にすると次のようなサイズが導かれます。

16px × 1.414 ≈ 22.6px
22.6px × 1.414 ≈ 32px
32px × 1.414 ≈ 45px

cssで表すと下記のようになります。

:root {
  --base-font-size: 16px;
  --scale-ratio: 1.414;
  --h1-size: calc(var(--base-font-size) * var(--scale-ratio) * var(--scale-ratio));
  --h2-size: calc(var(--base-font-size) * var(--scale-ratio));
  --p-size: var(--base-font-size);
}

h1 {
  font-size: var(--h1-size);
}

h2 {
  font-size: var(--h2-size);
}

p {
  font-size: var(--p-size);
}

この方法を使うと、フォントサイズの選定に一貫性が生まれ、自然に見やすいデザインが実現できます。

主なモジュラースケールの比率

  • 1.25(4:5) - 小さいサイズ差で繊細なデザインに向く
  • 1.414(√2) - 紙面デザイン(A4, A3)にも使われる
  • 1.618(黄金比) - 美しいバランスを生みやすい

行間・字間の調整

  • 行間(line-height): 1.5〜1.75倍が理想
  • 字間(letter-spacing): タイトルはやや広め、本文は標準
p {
  line-height: 1.6;
  letter-spacing: 0.02em;
}

スペーシングの統一

余白(マージン・パディング)の設計

一貫した余白を設定することで、統一感のあるレイアウトを作成できます。

:root {
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;
}

ボタンやカードの余白を統一することで、全体的な整合性が保たれます。

button {
  padding: var(--spacing-md) var(--spacing-lg);
}

レスポンシブデザインにおけるスペーシング

  • モバイル: コンパクトに
  • タブレット: 中間のスペース
  • デスクトップ: ゆったりしたスペース
.container {
  padding: 16px;
}
@media (min-width: 768px) {
  .container {
    padding: 24px;
  }
}

Material Design / Apple HIG から学ぶデザイン原則

  • カラーパレット: 主要色、アクセント色のバランス
  • タイポグラフィ: line-height, letter-spacing の統一
  • スペーシング: 4px, 8px, 16px のグリッドシステムを採用

アクセシビリティ向上のための実装支援

Web アクセシビリティとは、障害の有無にかかわらず、すべてのユーザーが快適にウェブサイトやアプリケーションを利用できるようにするための取り組みです。特に、視覚・聴覚・運動機能・認知能力などに制約のあるユーザーにも適切な情報提供や操作性を確保することが重要です。

アクセシビリティチェックリスト

以下の項目に対応することで、より多くのユーザーが利用しやすい環境を構築できます。

適切なコントラスト比(WCAG基準に準拠)

  • WCAG (Web Content Accessibility Guidelines) 2.1 では、最低限のコントラスト比として以下が推奨されています:
    • 一般的なテキスト:4.5:1 以上
    • 大きなテキスト(18pt または 14pt 太字以上):3:1 以上
    • UI コンポーネントやグラフィック:3:1 以上
  • 実装例
    • color-contrast() などのツールを活用し、デザイン段階でチェック
    • ダークモードやハイコントラストモードに対応する

キーボード操作が可能か確認

  • マウスを使わずに Tab キーだけでページ内を適切に移動できるか確認
  • Enter / Space / Arrow キーで操作できるようにする
  • tabindex を適切に設定し、フォーカスの順序を制御
    <button onClick={handleClick} tabIndex="0">クリック</button>
    

ARIA 属性を適切に設定

  • aria-label や aria-labelledby を活用し、スクリーンリーダーでのナビゲーションを向上
  • role 属性を適切に指定し、コンポーネントの意図を明確化
  • 実装例
    <button aria-label="メニューを開く"></button>
    

スクリーンリーダーでの操作をテスト

  • NVDA(Windows) や VoiceOver(Mac) を使用し、音声読み上げで適切に情報が伝わるか確認
  • aria-live を活用し、動的コンテンツの更新を通知
  • 実装例
    <div aria-live="polite">新しいメッセージがあります</div>
    

実装の工夫

alt 属性を適切に設定

  • 画像には alt 属性を指定し、適切な説明を記述
  • 装飾目的の画像は alt="" を指定し、スクリーンリーダーが読み上げないようにする
  • 実装例
    <img src="logo.png" alt="会社のロゴ" />
    

フォーム要素には適切な label を付与

  • labelfor 属性と id で関連付ける

  • プレースホルダーのみでなく、明確な label を設定する

  • 実装例

    <label for="email">メールアドレス</label>
    <input type="email" id="email" name="email" required />
    
  • alt 属性を適切に設定

  • フォーム要素には適切なlabelを付与

  • focushover の視認性を向上

focushover の視認性を向上

  • フォーカス時に視覚的なフィードバックを提供
  • :focus-visible:hover でスタイルを明確化
  • 実装例
    button:focus-visible {
      outline: 2px solid #005fcc;
      outline-offset: 2px;
    }
    

コードスタイルの整備

一貫性のあるコードスタイルと設計を維持することは、開発の効率性や可読性の向上、チーム開発におけるスムーズなコミュニケーションに不可欠です。本節では、具体的な手法を掘り下げて解説します。

ESLint(コードの静的解析)

ESLintは、JavaScriptおよびTypeScriptのコードを静的に解析し、潜在的なエラーやスタイルの不統一を検出するツールです。
開発者がコーディング規約を守りやすくし、バグを未然に防ぐための強力なサポートを提供します。

主な特徴

  • 静的解析:コードを実行せずに問題を検出
  • カスタマイズ可能なルールセット:プロジェクトごとのスタイルを設定可能
  • プラグイン拡張:ReactやTypeScript、アクセシビリティなどの特定用途向けルールを追加できる
  • 自動修正機能(--fix):簡単なスタイルの修正は自動化

ルールの設定方法

プロジェクトのルートディレクトリに .eslintrc.js(または .eslintrc.json)を作成し、ルールを定義します。

.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',  // ESLintの推奨ルールセットを適用
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier'  // Prettierとの競合を防ぐ
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'react',
    '@typescript-eslint',
    'import',
    'jsx-a11y',
    'tailwindcss',
  ],
  rules: {
    'no-console': 'warn', // console.logの使用を警告
    'no-unused-vars': 'warn', // 未使用の変数を警告
    'react/prop-types': 'off', // TypeScriptを使う場合は不要
    'tailwindcss/no-custom-classname': 'warn', // Tailwind CSSの命名規則をチェック
  },
};

代表的なカスタマイズ可能なルール

ルール 説明 設定例
no-console console.log の使用を警告または禁止 "no-console": "warn"
no-unused-vars 未使用の変数を警告 "no-unused-vars": "warn"
eqeqeq == ではなく === を強制 "eqeqeq": "error"
max-len 1行の最大文字数を指定 "max-len": ["error", { "code": 100 }]
camelcase 変数・関数名のキャメルケース強制 "camelcase": "error"

プラグインの活用

ESLintのプラグインを導入することで、ReactやTypeScript、アクセシビリティなどの特定の用途向けのルールを適用できます。

① eslint-plugin-import(import順序の統一)
モジュールの import の順番や未使用の import をチェックし、整理するためのプラグイン。

インストール

npm install eslint-plugin-import --save-dev

設定例

module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:import/recommended',
  ],
  rules: {
    'import/order': [
      'error',
      {
        'groups': ['builtin', 'external', 'internal'],
        'alphabetize': { 'order': 'asc', 'caseInsensitive': true }
      }
    ]
  }
};

チェックする項目

  • import/orderimport の順番(標準モジュール、外部ライブラリ、内部モジュールの順)
  • import/no-unresolved:解決できない import を防ぐ
  • import/no-duplicates:重複した import の検出

② eslint-plugin-jsx-a11y(アクセシビリティのチェック)

インストール

npm install eslint-plugin-jsx-a11y --save-dev

設定例

module.exports = {
  "plugins": ["jsx-a11y"],
  "rules": {
    'jsx-a11y/anchor-is-valid': 'warn', // 無効な `<a>` タグの警告
    'jsx-a11y/no-noninteractive-element-interactions': 'warn' // 非インタラクティブ要素のイベントリスナー警告
  },
};

チェックする項目

  • jsx-a11y/anchor-is-valid<a> タグが正しい href を持っているか
  • jsx-a11y/no-noninteractive-element-interactionsdiv などの非インタラクティブ要素にイベントハンドラがついていないか
  • jsx-a11y/alt-text:画像に alt 属性が適切に設定されているか

また、下記のように設定すると全てのルールが適用されます。

{
  "extends": ["plugin:jsx-a11y/recommended"]
}

③ eslint-plugin-tailwindcss(Tailwind CSSのクラス順序チェック)

インストール

npm install eslint-plugin-tailwindcss --save-dev

設定例

module.exports = {
  plugins: ['tailwindcss'],
  rules: {
    'tailwindcss/no-custom-classname': 'warn', // Tailwind CSSに存在しないクラス名を警告
    'tailwindcss/classnames-order': 'warn' // クラスの順序をチェック
  },
};

チェックする項目

  • tailwindcss/no-custom-classname:Tailwind CSSにないクラス名を防ぐ
  • tailwindcss/classnames-order:クラスの順序を公式推奨に従って整理

Prettier(コードフォーマットの統一)

Prettierは、コードフォーマット(整形)を強制的に統一するツールです。ESLintが主に「コードの品質」や「エラーチェック」を目的とするのに対し、Prettierは「コードのスタイル(フォーマット)」を自動で整えることを目的としています。

例えば、Prettierを導入すると以下のような書式の違いが統一されます。

Before(不統一なコード)

function greet(name) {
console.log(  "Hello, " + name  + "!" );
}

After(Prettier適用後)

function greet(name) {
  console.log("Hello, " + name + "!");
}
  • インデントを統一(スペースのずれを修正)
  • ダブルクォートを適用(設定によって変更可能)
  • スペースの不適切な使用を修正

Prettierを使用すると、チーム開発や個人プロジェクトで以下のようなメリットがあります。

1. インデントやスペースの統一

  • Prettierはコードのインデント(スペースやタブ)を統一し、読みやすい形にフォーマットします。
  • 例えば、tab か space かの選択や、スペースの数(例:2スペース or 4スペース)も統一可能です。

2. シングルクォート/ダブルクォートの統一

  • JavaScriptやTypeScriptでは、シングルクォート (') とダブルクォート (") の両方が使えますが、Prettierを使うとプロジェクト内の統一が可能です。

Before

console.log("Hello, World!"); // ダブルクォート

After(Prettier適用後)

console.log('Hello, World!'); // シングルクォートに統一

3. 行の折り返しルールの統一

  • 長すぎる行を適切な場所で自動的に改行し、可読性を向上させます。
  • 例えば、printWidth の設定を 80 にすると、長い行が80文字で自動的に折り返されます。

4. チーム開発でのコードスタイルの統一

  • コードレビューの際に「スペースの入れ方が違う」「クォートがバラバラ」といった指摘が不要になる。
  • 自動フォーマットを導入することで、開発者はロジックや設計に集中できる。

PrettierとESLintの統合

Prettierはコードのフォーマットを統一しますが、ESLintも一部フォーマットルールを持っています。そのため、ESLintとPrettierのルールが競合することがあります。

例えば、ESLintで indent: ["error", 2] を指定していても、Prettierが tabWidth: 4 に設定されていると、インデントのルールが競合します。

この競合を解決するために eslint-config-prettier を導入しPrettierのルールと競合するESLintの設定を無効化します。

インストール

npm install --save-dev eslint-config-prettier

設定例

{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ]
}

Prettierの設定方法

.prettierrc.json
{
  "printWidth": 100,       // 1行の最大文字数
  "tabWidth": 2,           // インデントのスペース数
  "useTabs": false,        // タブの代わりにスペースを使用
  "singleQuote": true,     // シングルクォートを使用
  "semi": false,           // セミコロンを省略
  "trailingComma": "all"   // 末尾のカンマを追加(ESLintのルールと統一)
}

Prettierの使用方法

Prettierはコマンドラインまたはエディタのプラグインを使って実行できます。

  1. コマンドラインで実行
npx prettier --write .
  • --write を付けると、対象ファイルをフォーマットして上書きします。
  1. VSCodeで自動フォーマット
    VSCodeでPrettierを有効にすると、ファイル保存時に自動フォーマットできます。
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}
  • formatOnSave: true を設定すると、ファイル保存時に自動でPrettierが実行されます。

コードレビューのルール策定

チーム開発では、コードレビューのルールを明確に定めることで、品質を一定に保つことができます。

  • レビューの観点

    • コードスタイルの遵守(ESLint/Prettierの適用)
    • 一貫性のあるコンポーネント設計
    • 冗長なコードの削減(不要な再レンダリングの防止)
    • 型の適切な使用(TypeScriptの厳格な型付け)
    • アクセシビリティ(a11y)の考慮
  • GitHubのプルリクエスト運用

    • PRの説明テンプレートを用意(何を変更したのか、影響範囲、確認方法など)
    • 自動チェック(CI/CDでESLint、Prettier、テスト実行)

PRテンプレート例

### 変更内容
- xxxの機能を追加
- xxxのバグを修正

### 確認方法
1. xxxを実行する
2. xxxの挙動を確認する

### 影響範囲
- xxxのコンポーネントに影響あり
- xxxのテストも確認済み

コンポーネントの命名規則の統一

命名規則を統一することで、コードの可読性や検索性が向上します。

  • コンポーネントの命名
    • PascalCase(例:UserCardProductList
  • CSSの命名
    • BEM(例:.card__title.button--primary
    • Tailwind CSSを使う場合は、クラスを直接記述し、カスタムCSSは最小限にする

開発者・デザイナー向けのドキュメント作成

開発者とデザイナーがスムーズに連携し、認識のズレを防ぐためには、適切なドキュメントの作成が不可欠です。本記事では、必要なドキュメントの種類と、効果的なドキュメント作成のポイントについて詳しく解説します。

必要なドキュメントの種類

1. デザインシステムドキュメント

デザインの統一性を保つために、以下の情報を明確に記載します。

  • カラーパレット
    • プライマリー・セカンダリーカラーの定義
    • 各カラーの用途(背景・ボタン・テキストなど)
    • カラーコード(Hex / RGB / HSL)
  • タイポグラフィ
    • フォントファミリー(例: Inter, Roboto)
    • フォントサイズ(見出し・本文・キャプション)
    • 行間や文字間の指定
  • コンポーネント仕様
    • ボタン、フォーム、モーダル、カードなどのコンポーネント定義
    • 状態(ホバー・アクティブ・無効状態)
    • コンポーネントのデザイン例(FigmaやStorybookで管理)

おすすめの管理ツール:

  • Figma / Adobe XD: デザインの可視化
  • Storybook: UIコンポーネントのドキュメント化
  • Zeroheight / Notion: デザインシステムの一元管理

2. コーディングガイドライン

プロジェクトの可読性と保守性を向上させるために、コードの書き方を統一します。

  • フォーマット
    • ESLint / Prettier でのコード整形ルール
    • インデント(2スペース or 4スペース)
  • ディレクトリ構成
      /src
        /components   # UIコンポーネント
        /pages        # ページ単位のコンポーネント
        /utils        # 共通関数
        /api          # API通信処理
    
  • 命名規則
    • 変数: camelCase (userName, fetchData)
    • コンポーネント: PascalCase (UserCard, HeaderNav)
    • 関数: camelCase (handleClick, getUserData)
    • ファイル: kebab-case.tsx (user-card.tsx, fetch-data.ts)

おすすめの管理ツール:

  • Notion / Confluence: コーディングルールの共有
  • GitHub Wiki: リポジトリ内で管理
  • Husky / lint-staged: コードフォーマットの自動適用

効果的なドキュメント作成のポイント

  1. 情報の一元管理

    • ドキュメントが分散すると、どれが最新かわからなくなり混乱します。
    • Notion, Confluence, GitHub Wiki などを活用し、チームで参照しやすい場所にまとめます。
  2. 定期的なメンテナンス

    • 情報が古くなると、逆に混乱を招く
    • レビューサイクルを決めて、定期的に更新(例: 月1回)
    • 変更履歴を管理(Notionのバージョン履歴機能を活用)

可用性テストとユーザビリティ向上

システムの可用性(Availability)とユーザビリティ(Usability)は、ユーザーがシステムをスムーズに利用できるかどうかに直結する重要な要素です。可用性テストを適切に実施し、ユーザビリティを向上させることで、システムの信頼性や使いやすさを高めることができます。

可用性テスト(Availability Testing)の実施

可用性テストとは、システムが適切に稼働し続けるか、障害時に迅速に復旧できるかを検証するテストです。また、システムのパフォーマンスやUX(ユーザーエクスペリエンス)を向上させるための施策も含まれます。

1. ユーザーテストの実施

目的: 実際のユーザーがどのようにシステムを利用するのかを観察し、問題点を特定する

方法:

  • ユーザーインタビュー: ユーザーにシステムを使用してもらい、フィードバックを収集
  • シナリオベースのテスト: 事前に用意したユースケース(例: 商品購入、アカウント作成)をユーザーに実行してもらい、課題を特定
  • リモートテスト: ユーザーが実際の環境で使用する様子を記録し、問題点を分析

ポイント:

  • 単なる主観的なフィードバックだけでなく、行動データ(どこでつまずいたか)も取得する

  • テスト対象を適切に選定(ターゲットユーザーに近いユーザーを選ぶ)

  • 記録・分析を行い、次の改善施策に活かす

  • ユーザーテストを実施し、実際の利用シナリオを検証

  • A/Bテストを活用し、デザインやUXの改善をデータに基づいて判断

  • Heatmapや分析ツールを使用し、ユーザー行動を可視化

2. A/Bテストの活用

目的: 異なるデザインや機能を比較し、ユーザーにとって最適なものをデータに基づいて判断

方法:

  • 2つ以上のバージョン(A/B)をユーザーにランダムに表示し、どちらがより良い結果をもたらすかを測定
  • クリック率、コンバージョン率、離脱率などの指標を比較
  • A/Bテストの例:
    • CTAボタンの色や文言(「購入する」 vs 「今すぐ注文」)
    • フォーム入力の簡略化(ステップ数を減らす vs そのまま)
    • ユーザー登録フローの変更(ソーシャルログイン導入 vs メール登録のみ)

ポイント:

  • 目的を明確にする: 何を改善したいのか(例: コンバージョン率向上)
  • 十分なデータを収集する: 統計的に有意なサンプル数を確保
  • 1回に1つの要素を変更: 何が影響したのかを明確にするため

3. Heatmapや分析ツールを活用

目的: ユーザーの行動を可視化し、問題点を特定

ツール:

  • Heatmapツール: ユーザーがどこをクリックしたか、どの部分でスクロールを止めたかを視覚的に表示(例: Hotjar, Crazy Egg)
  • Google Analytics: ページの滞在時間、直帰率、コンバージョン率を分析
  • セッションリプレイ: 実際のユーザーの行動を録画し、どのようにページを操作しているかを確認

活用例:

  • 「CTAボタンがクリックされていない → 目立つ位置に配置、色を変更」
  • 「ユーザーが途中で離脱 → フォームを簡略化」
  • 「スクロール率が低い → 重要な情報を上部に配置」

ユーザビリティ向上のための施策

ユーザビリティとは、「ユーザーが直感的に操作でき、ストレスなく目的を達成できるか」を指します。以下の施策を実施することで、より快適なUXを提供できます。

1. 明確なナビゲーションと情報構造の最適化

目的: ユーザーが迷わず目的のページにたどり着けるようにする

施策:

  • パンくずリストの導入: ユーザーが現在の位置を把握しやすくする
  • カテゴリ分けの最適化: ユーザーが直感的に理解できるグループ分け
  • 検索機能の強化: オートコンプリートやフィルタ機能を追加

ポイント:

  • 情報が多すぎると迷う → シンプルでわかりやすい構造
  • メニューのラベルは具体的に(「サービス」ではなく「料金プラン」)

2. インタラクティブな要素のフィードバック

目的: ユーザーの操作に対して適切なフィードバックを提供し、使いやすさを向上

施策:

  • ホバー時のスタイル変更: ボタンやリンクがクリック可能であることを視覚的に示す
  • ローディングインジケーター: 読み込み中であることをユーザーに知らせる(スピナー、プログレスバー)
  • アニメーションの活用: 遷移や状態変化をスムーズにする(例: モーダルウィンドウのフェードイン)

ポイント:

  • 過度なアニメーションは避ける(動作が遅くなるとストレス)
  • クリック可能な要素は視覚的に強調(色や影を使う)

3. ユーザーの入力を支援

目的: フォーム入力の負担を軽減し、エラーを防ぐ

施策:

  • プレースホルダーの活用: 例: 「例: yourname@example.com
  • リアルタイムバリデーション: 入力ミスがある場合、その場でエラーメッセージを表示
  • オートフィル対応: 住所入力の自動補完など

ポイント:

  • フォームはできるだけ短く(不要な項目は削減)
  • 「入力エラーです」ではなく、具体的に「パスワードは8文字以上必要です」と伝える

さいごに

デザインシステムは、一度作れば終わりではなく、継続的に進化させることが重要 です。プロジェクトの規模や要件の変化に応じて、適切に更新・改善しながら運用することで、より価値のあるシステムとなります。

本記事で紹介したUIフレームワークの活用、ガイドラインの策定、アクセシビリティの強化、ドキュメントの整備 などの手法を活かしながら、自社・自プロジェクトに最適なデザインシステムを構築してみてください。継続的な改善とチームの協力によって、より洗練されたUI/UXの提供が可能になるはずです。

Xでシェア
Facebookでシェア
LinkedInでシェア

記事に関するお問い合わせ📝

記事の内容に関するご質問、ご意見などは、下記よりお気軽にお問い合わせください。
ご質問フォームへ

技術支援などお仕事に関するお問い合わせ📄

技術支援やお仕事のご依頼に関するお問い合わせは、下記よりお気軽にお問い合わせください。
お問い合わせフォームへ

関連する技術ブログ

弊社の技術支援サービス

お問い合わせ

経営と現場をつなぐ“共創型”の技術支援。
成果に直結するチーム・技術・プロセスを共に整えます。

お問い合わせ