Mermaidのデザインが物足りない?Tailwindで拡張して設計書品質に

Mermaidの見た目、もうちょっとなんとかならんか

ども!Mermaidで図を作るたびに「構造は最高なんだけど、見た目がなぁ…」と思ってた龍ちゃんです。

Claude CodeでMermaid図を作成する」でMermaid図の自動生成について書きました。Mermaidはコードで構造を書けるから、フローチャートやシーケンス図がサクッと作れます。AIに「こういう図作って」って言えば一発で出てくるんですよね。

ただ、デフォルトのデザインがシンプルすぎるんですよね。設計書やブログに貼るにはちょっと素朴。

HTML+Tailwind CSSで図解を丸投げする方法も試したんですよ。装飾の自由度は高いんですけど、フロー図やシーケンス図をCSSで手動配置するのが辛い。特に矢印の表現が鬼の難易度です。Mermaidが自動でやってくれる部分を手で書くのはしんどいです。

じゃあ合体させたらどうだ、と。

Mermaidの構造表現力 + Tailwind CSSの装飾力。Mermaidに図の構造を任せて、周りの見た目はTailwindで自由に作れます。これを1つのHTMLファイルにまとめてPNGに変換します。

今回の内容です。

  • コピペで使えるHTMLテンプレート2種(右サイド注釈型 / 下部グリッド注釈型)
  • 色を揃えるカスタマイズのコツ
  • 実際にぶつかった壁と対処法
  • PNG変換の手段3つ

まず完成形を見せます

こういうのが作れます。

左がMermaidで描画したシーケンス図、右がTailwind CSSで装飾した注釈パネル。これ、1つのHTMLファイルから出てきます。

ポイントは、Mermaid図の色とTailwind装飾の色が揃ってるところですね。青系で統一してるから、「Mermaidの部分だけ浮いてる」みたいなことにならない。

注釈パネルには設計ポイント、セキュリティ考慮、エラーハンドリングみたいな文脈情報を書けます。Mermaid図だけだと「何が起きてるか」は分かるけど「なぜこうしたか」は伝わらないんですよね。注釈パネルがその「なぜ」を補ってくれます。

関連記事: 仕様書の図でAIの理解と人間の視認性を両立する方法に関しては「仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン」で詳しく書いてます。AIに図の構造を正確に伝えたい人はこちらもどうぞ。

テンプレートA: 右サイド注釈型

ここからが本題です。コピペして使えるHTMLテンプレートを2種類用意しました。

仕組みはシンプルで、1つのHTMLにTailwind CDNとMermaid CDN(ESM版)を同時に読み込んでるだけです。2つのCDNは競合しません(検証済み)。テンプレートをコピペすればそのまま動きます。色のカスタマイズについてはテンプレートの後で説明しますね。

まずはテンプレートA。冒頭で見せた完成形がこれです。左にMermaid図、右に注釈パネルを並べるレイアウトですね。

向いてる場面: シンプルな図(ノード8個以下)に設計ポイントを3-4個添えたいとき

キャンバスサイズ: 1280x720px

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Level 2: Mermaid + Tailwind CSS Decoration</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="w-[1280px] h-[720px] m-0 p-0 overflow-hidden bg-white">
    <div class="w-full h-full flex gap-6 p-10">
        <!-- 左: Mermaid図 -->
        <div class="flex-1 border-2 border-blue-300 rounded-lg p-6 bg-blue-50">
            <h2 class="text-xl font-bold text-blue-900 mb-4">認証フローのシーケンス図</h2>
            <div class="mermaid">
sequenceDiagram
    participant C as クライアント
    participant S as サーバー
    participant DB as データベース
    C->>+S: ログインリクエスト
    S->>+DB: ユーザー照合
    DB-->>-S: 認証結果
    alt 認証成功
        S-->>C: アクセストークン発行
    else 認証失敗
        S-->>C: エラーレスポンス(401)
    end
            </div>
        </div>

        <!-- 右: 注釈パネル -->
        <div class="w-72 flex flex-col gap-3">
            <div class="bg-yellow-50 border border-yellow-300 rounded p-3">
                <h3 class="text-sm font-bold text-yellow-800">設計ポイント</h3>
                <p class="text-xs text-yellow-700">DB直接参照を避け、サービス層を経由させることで結合度を低減</p>
            </div>
            <div class="bg-green-50 border border-green-300 rounded p-3">
                <h3 class="text-sm font-bold text-green-800">セキュリティ考慮</h3>
                <p class="text-xs text-green-700">トークンはJWT形式、有効期限15分で自動失効</p>
            </div>
            <div class="bg-red-50 border border-red-300 rounded p-3">
                <h3 class="text-sm font-bold text-red-800">エラーハンドリング</h3>
                <p class="text-xs text-red-700">認証失敗時は具体的なエラー原因を返さない(セキュリティ対策)</p>
            </div>
        </div>
    </div>

    <script type="module">
        import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
        mermaid.initialize({
            startOnLoad: true,
            theme: 'base',
            themeVariables: {
                primaryColor: '#dbeafe',
                primaryBorderColor: '#3b82f6',
                lineColor: '#6b7280',
                fontFamily: 'system-ui, sans-serif'
            }
        });
    </script>
</body>
</html>

使い方はシンプルで、3箇所を差し替えるだけです。

  1. Mermaid記法の部分<div class="mermaid"> の中身)を自分の図に差し替える
  2. 注釈パネルの内容(右側の3つのパネル)を自分の設計ポイントに差し替える
  3. themeVariablesで色を変えたければカラーコードを調整する

注釈パネルは増減しても大丈夫です。3個が収まりいいですけど、2個でも4個でもレイアウトは崩れません。

色の統一について

完成形の画像を見て「Mermaid図と注釈パネルの色が揃ってるな」と思った人もいるかもしれません。これはテンプレート末尾の themeVariables でMermaid図の配色をTailwindのカラーパレットに合わせてるからです。

themeVariables: {
    primaryColor: '#dbeafe',       // Tailwind blue-100
    primaryBorderColor: '#3b82f6', // Tailwind blue-500
    lineColor: '#6b7280',          // Tailwind gray-500
    fontFamily: 'system-ui, sans-serif'
}

色を変えたいときはここのカラーコードを差し替えてください。Tailwindのカラーパレットから持ってくると注釈パネル側と揃えやすいです。

1つ注意点として、Mermaid図の中にTailwindクラスは効きません。Mermaid図はSVGとして生成されるんで、外部CSSが適用できないんですよね。色のカスタマイズは themeVariables 経由のみです。

テンプレートB: 下部グリッド注釈型

テンプレートAだと、図が複雑になったときに左側のスペースが足りなくなります。シーケンス図で参加者が4人以上いたり、メッセージが10本近くあると、右の注釈パネルに幅を取られて図が窮屈になるんですよね。

そういうときはテンプレートBです。図を上部に全幅で配置して、注釈パネルは下部にグリッドで並べます。

向いてる場面: 複雑な図(10ステップ近いシーケンス、状態遷移図)で図に全幅を使いたいとき

キャンバスサイズ: 1280x1080px(縦に拡張)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OAuth 2.0 認可コードフロー</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        .mermaid svg {
            transform: scale(3.2);
            transform-origin: center center;
        }
    </style>
    <script type="module">
        import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
        mermaid.initialize({
            startOnLoad: true,
            theme: 'base',
            sequence: {
                diagramMarginX: 10,
                diagramMarginY: 10,
                actorMargin: 80,
                messageMargin: 40
            },
            themeVariables: {
                primaryColor: '#e0f2fe',
                primaryBorderColor: '#0284c7',
                primaryTextColor: '#0c4a6e',
                lineColor: '#64748b',
                fontFamily: 'system-ui, sans-serif'
            }
        });
    </script>
</head>
<body class="w-[1280px] h-[1080px] m-0 p-0 overflow-hidden bg-white">
    <div class="w-full h-full flex flex-col p-8 gap-6">
        <!-- 上部: タイトル -->
        <div>
            <div class="text-lg font-bold text-gray-800">OAuth 2.0 認可コードフロー</div>
            <div class="text-sm text-gray-500">ソーシャルログイン実装の標準パターン</div>
        </div>

        <!-- 中央: 図(全幅) -->
        <div class="flex-1 border border-gray-200 rounded-lg p-6 bg-gray-50 flex items-center justify-center">
            <div class="mermaid">
sequenceDiagram
    actor U as ユーザー
    participant App as Webアプリ
    participant Auth as 認可サーバー
    participant API as リソースサーバー
    U->>App: ログインボタンクリック
    App->>Auth: 認可リクエスト(client_id, redirect_uri, scope)
    Auth->>U: ログイン画面表示
    U->>Auth: 認証情報入力
    Auth->>App: 認可コード(code)
    App->>Auth: トークンリクエスト(code, client_secret)
    Auth->>App: アクセストークン + リフレッシュトークン
    App->>API: APIリクエスト(Bearer token)
    API->>App: リソースデータ
    App->>U: ユーザー情報表示
            </div>
        </div>

        <!-- 下部: 注釈パネル(横並び) -->
        <div class="grid grid-cols-4 gap-3">
            <div class="bg-blue-50 border border-blue-200 rounded-lg p-3">
                <div class="text-sm font-bold text-blue-800">フロー概要</div>
                <div class="text-xs text-blue-700 mt-1">RFC 6749準拠の認可コードグラント。SPAではPKCE拡張を推奨。</div>
            </div>
            <div class="bg-amber-50 border border-amber-200 rounded-lg p-3">
                <div class="text-sm font-bold text-amber-800">セキュリティ要件</div>
                <div class="text-xs text-amber-700 mt-1 space-y-1">
                    <div>state パラメータでCSRF対策</div>
                    <div>client_secret はサーバー側で保持</div>
                    <div>redirect_uri の完全一致検証</div>
                </div>
            </div>
            <div class="bg-green-50 border border-green-200 rounded-lg p-3">
                <div class="text-sm font-bold text-green-800">実装チェックリスト</div>
                <div class="text-xs text-green-700 mt-1 space-y-1">
                    <div>トークンの安全な保存(httpOnly cookie)</div>
                    <div>リフレッシュトークンのローテーション</div>
                    <div>スコープの最小権限原則</div>
                </div>
            </div>
            <div class="bg-gray-100 border border-gray-200 rounded-lg p-3">
                <div class="text-sm font-bold text-gray-700">補足</div>
                <div class="text-xs text-gray-600 mt-1">アクセストークンの有効期限は15分〜1時間が一般的。期限切れ時はリフレッシュトークンで自動更新。</div>
            </div>
        </div>
    </div>
</body>
</html>

テンプレートAとの違いは3つです。

  1. キャンバスが縦に拡張(720px → 1080px)。図に余裕ができます
  2. 注釈パネルが下部グリッド。図が全幅を使えるんで、参加者が4人いても窮屈になりません
  3. CSS transformでMermaid図を拡大scale(3.2))。Mermaidは複雑な図を自動縮小するんで、それを補正してます

scaleの調整について

テンプレートBの scale(3.2) は、上のOAuth 2.0の例(参加者4人・メッセージ10本)に合わせた値です。自分の図に差し替えたら、scaleも調整が必要です。

Mermaidは図の複雑度に応じて自動縮小するんですけど、その縮小率が図ごとに変わるんですよね。なので 図を差し替えるたびにscaleを微調整する のが前提の設計です。

調整の手順はシンプルで、HTMLファイルをブラウザで開いて、文字が読める大きさになるまで scale の数値を上げ下げするだけです。目安としてはこんな感じ。

図の複雑度scale目安
シンプル(参加者2-3人、メッセージ5本以下)1.5〜2.0
中程度(参加者3-4人、メッセージ8本前後)2.5〜3.5
複雑(参加者4人以上、メッセージ10本以上)3.0〜4.0

どっちを使う?

条件テンプレート
図がシンプル(ノード8以下)A: 右サイド注釈型
図が複雑、横に広がるB: 下部グリッド注釈型
注釈が少ない(2-3個)A
注釈が多い(4個以上)B

迷ったらまずテンプレートAで試して、図が窮屈ならBに切り替える、でいいと思います。

ぶつかった壁と対処

検証してて何度かハマったので、先に共有しておきます。

ノード数には上限がある

Mermaidは図の要素が増えると自動で縮小するんですよね。1280pxの幅に収めようとするから、ノードが多いと文字が潰れて読めなくなります。

実際に検証して、このくらいが上限だなというラインが見えました。

図の種類推奨上限超えるとどうなるか
フローチャート8-10ノード文字が小さくなって読めない
シーケンス図4参加者・8メッセージラベルが長いと自動縮小される
状態遷移図8-10状態縦に伸びてキャンバスからはみ出す

上限を超えそうなときは、図を分割するか、テンプレートBでキャンバスを拡張するのがいいです。

サイズ問題の対策3種

実際にぶつかったサイズ問題と、それぞれの対処法です。

症状対策やり方
図がキャンバスからはみ出すキャンバスを拡張するh-[720px]h-[1080px] に変更。PNG変換時も --height 1080 を指定
図が小さすぎて読めないCSS transformで拡大.mermaid svg { transform: scale(X); } を追加
右の注釈パネルが図を圧迫する注釈を下部に移動テンプレートAからBに切り替える

この3つの対策は組み合わせられます。テンプレートBはキャンバス拡張 + CSS transform + 下部グリッドの3つ全部入りですね。制約はあるけど対策は全部見つかってるんで、複雑な図はまずBを試してみてください。

PNG変換 — 3つの手段

HTMLファイルが完成したら、PNG画像に変換してブログや設計書に貼れます。手段は3つあって、好みと環境に合わせて選んでください。

手段自動化セットアップ向いてる用途
CLIツール(html-screenshot)できるPython + Playwright量産やCI/CD
Playwright MCPできるMCP設定Claude Code連携
ブラウザで直接開く手動なし手軽に確認

CLIツール

uv run html-screenshot --file template-a.html --output template-a.png

以前の記事で紹介したhtml-screenshotツールがそのまま使えます。改修なしでMermaid CDNの読み込みにも対応してました。Playwrightの wait_until="networkidle" がCDN読み込み完了を待ってくれるんで、Mermaid図の描画が終わってからスクリーンショットを撮ってくれます。

テンプレートBのように高さを変えたい場合は --height 1080 を付けます。

Playwright MCP

Claude CodeからPlaywrightのブラウザ操作を直接呼び出す方法もあります。HTMLファイルを開いてスクリーンショットを撮る操作がMCPのツールで完結します。Playwright MCPの記事で詳しく書いてるんで、Claude Code使ってる人はこっちが楽かもしれません。

ブラウザで直接開く

一番手軽なのはHTMLファイルをブラウザで直接開くことですね。Mermaid CDNが読み込まれて図がそのまま描画されます。PNG変換は手動(ブラウザのDevToolsやOS標準のスクリーンショット)になりますけど、「ちょっと確認したい」くらいならこれで十分です。

まとめ

ノード数の上限やサイズ問題はありましたけど、全部対処法が見つかりました。制約を把握しておけばハマることはないです。

今回のポイントです。

「構造はMermaid、装飾はTailwind」の役割分担。Mermaidが得意な構造の自動レイアウト(矢印の接続、参加者の配置、分岐の描画)はMermaidに任せて、周りの装飾(注釈パネル、色統一、レイアウト)はTailwind CSSで自由に作る。

テンプレートの使い分けはシンプルです。

条件テンプレート
シンプルな図 + 注釈少なめA: 右サイド注釈型(1280×720)
複雑な図 + 注釈多めB: 下部グリッド注釈型(1280×1080)

あと、おまけとして1つ。このテンプレートで作った図はAI連携にも強いです。Mermaidのソースコードは宣言的な記法(sequenceDiagramgraph TD とか)なんで、AIが構造を正確に読み取れます。注釈パネルに設計意図を書いておけば、人間が見ても、AIが読んでもどっちにも伝わる。この辺の話は仕様書の図にソースコードを添える設計パターンで詳しく書いてるんで、興味あれば読んでみてください。

もう1つ。このテンプレートを毎回コピペするのも手ですけど、Claude CodeのSKILL機能にreference(参考例)として登録しておくと、「シーケンス図作って」と言うだけでテンプレートに沿った図が出てきます。テンプレートのクオリティがそのままSKILLのクオリティになるんで、良いテンプレートを貯める = 図解の品質を底上げする、という流れができます。コピペ用テンプレートとSKILL化、好きなほうで使ってください。

PlantUML編も書きました。Mermaidが苦手な図種(アクティビティ図、ユースケース図、コンポーネント図)をPlantUMLでカバーする話です。「PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる」をどうぞ。

ほなまた〜

関連ブログ

今回の記事はシリーズの一部です。Mermaid図の生成からHTML図解、仕様書への活用まで、一連の流れで読めます。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
エンジニア募集中!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です