組織図(Organization Chart)— HTML/CSSのみ

グラフ・チャート 初級

このコンポーネントについて

組織図は、社内の部署構造や責任範囲を階層で見せるための図解UIです。 このページでは、ネストした <ul> / <li> と CSS の ::before / ::after 疑似要素だけで、親子関係の接続線を描く実装を紹介します。 JavaScriptや外部ライブラリを使わないため、社内ポータル・管理画面・印刷用ページにも組み込みやすい構成です。

  • Pattern 1 — 基本の縦型組織図 — 社長、部、課の3階層を ul/li のネストで表現。接続線はCSSのborderで描く
  • Pattern 2 — カード型ノード — 役職、氏名、部署ラベルを持つカード型ノードにして、業務アプリにそのまま置きやすい見た目にする
  • 横スクロール容認 — 小画面で無理に縦積みに変形せず、親子関係の線が崩れないようにする

実装のポイント・注意点

組織図のHTMLは、見た目のためにすべてを div で並べるより、階層の意味がそのまま伝わる ul/li で持つのがおすすめです。 CSSが読み込まれない環境でもリストとして読めるため、あとから部署名を差し替えるときも構造を追いやすくなります。 接続線は線用の空要素を増やさず、子リストと各 li の疑似要素に border-top / border-left を指定して描きます。

人数や部署が増えると、組織図はどうしても横に広がります。 スマホ幅で無理に折り返すと、どの部署がどの親に属するのか分かりにくくなるため、このサンプルでは overflow-x: auto で横スクロールを許可します。 印刷用途では背景色が消える場合があるので、@media print で枠線と接続線が残るように調整しています。

なお、クリックで展開・折りたたみしたい階層リストは ツリービュー — 展開・折りたたみ、チェックボックスで階層選択したい場合は ツリービュー — チェックボックス連動 が向いています。 このページは、静的HTMLで組織構造を図として見せる用途に絞っています。

HTML・CSSのみで実装しており、フレームワークや外部ライブラリ不要でコピペすぐに使えます。

デモ

Pattern 1 — 基本の縦型組織図

  • 代表取締役
    • 営業部
      • 第一営業課
      • 第二営業課
    • 開発部
      • フロントエンド課
      • バックエンド課
    • 管理部
      • 人事課
      • 経理課

小さい画面では横にスクロールして全体を確認できます。

Pattern 2 — カード型ノード

  • 代表取締役 山田 太郎 経営
    • 営業部長 佐藤 花子 営業部
      • 課長 鈴木 一郎 第一営業課
      • 課長 高橋 美咲 第二営業課
    • 開発部長 田中 健 開発部
      • 課長 伊藤 直人 フロントエンド課
      • 課長 小林 葵 バックエンド課

カード型にしても、HTMLの階層構造はPattern 1と同じです。

サンプルソース

3つのファイルを同じフォルダに保存し、index.html をブラウザで開くとすぐに動作確認できます。
ファイル名:index.html / style.css / script.js — 保存時の文字コードは UTF-8 を指定してください(Shift-JISだと日本語が文字化けします)。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>組織図 サンプル</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>

<!-- Pattern 1: 基本の縦型組織図 -->
<section class="org-section">
  <h2 class="org-title">Pattern 1 — 基本の縦型組織図</h2>
  <div class="org-scroll" tabindex="0" aria-label="基本の組織図">
    <ul class="org-chart">
      <li>
        <div class="org-node org-node--top">代表取締役</div>
        <ul>
          <li>
            <div class="org-node org-node--dept">営業部</div>
            <ul>
              <li><div class="org-node org-node--team">第一営業課</div></li>
              <li><div class="org-node org-node--team">第二営業課</div></li>
            </ul>
          </li>
          <li>
            <div class="org-node org-node--dept">開発部</div>
            <ul>
              <li><div class="org-node org-node--team">フロントエンド課</div></li>
              <li><div class="org-node org-node--team">バックエンド課</div></li>
            </ul>
          </li>
          <li>
            <div class="org-node org-node--dept">管理部</div>
            <ul>
              <li><div class="org-node org-node--team">人事課</div></li>
              <li><div class="org-node org-node--team">経理課</div></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</section>

<!-- Pattern 2: カード型ノード -->
<section class="org-section">
  <h2 class="org-title">Pattern 2 — カード型ノード</h2>
  <div class="org-scroll" tabindex="0" aria-label="カード型ノードの組織図">
    <ul class="org-chart org-chart--cards">
      <li>
        <div class="org-card org-card--top">
          <span class="org-role">代表取締役</span>
          <strong class="org-name">山田 太郎</strong>
          <span class="org-dept">経営</span>
        </div>
        <ul>
          <li>
            <div class="org-card org-card--sales">
              <span class="org-role">営業部長</span>
              <strong class="org-name">佐藤 花子</strong>
              <span class="org-dept">営業部</span>
            </div>
            <ul>
              <li>
                <div class="org-card org-card--sales">
                  <span class="org-role">課長</span>
                  <strong class="org-name">鈴木 一郎</strong>
                  <span class="org-dept">第一営業課</span>
                </div>
              </li>
              <li>
                <div class="org-card org-card--sales">
                  <span class="org-role">課長</span>
                  <strong class="org-name">高橋 美咲</strong>
                  <span class="org-dept">第二営業課</span>
                </div>
              </li>
            </ul>
          </li>
          <li>
            <div class="org-card org-card--dev">
              <span class="org-role">開発部長</span>
              <strong class="org-name">田中 健</strong>
              <span class="org-dept">開発部</span>
            </div>
            <ul>
              <li>
                <div class="org-card org-card--dev">
                  <span class="org-role">課長</span>
                  <strong class="org-name">伊藤 直人</strong>
                  <span class="org-dept">フロントエンド課</span>
                </div>
              </li>
              <li>
                <div class="org-card org-card--dev">
                  <span class="org-role">課長</span>
                  <strong class="org-name">小林 葵</strong>
                  <span class="org-dept">バックエンド課</span>
                </div>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</section>

<script src="./script.js"></script>
</body>
</html>
:root {
  --org-ink: #172033;
  --org-muted: #657184;
  --org-line: #AAB6C8;
  --org-surface: #FFFFFF;
  --org-soft: #F6F8FB;
  --org-border: #DDE4EF;
  --org-blue: #2B7FE8;
  --org-green: #16A085;
  --org-amber: #B7791F;
}

body {
  margin: 0;
  padding: 24px;
  font-family: sans-serif;
  color: var(--org-ink);
  background: var(--org-soft);
}

.org-section {
  margin-bottom: 48px;
}

.org-title {
  margin: 0 0 16px;
  font-size: 18px;
}

.org-scroll {
  overflow-x: auto;
  padding: 18px 12px 20px;
  background: #FFFFFF;
  border: 1px solid var(--org-border);
  border-radius: 8px;
}

.org-chart,
.org-chart ul {
  display: flex;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.org-chart {
  min-width: max-content;
}

.org-chart ul {
  position: relative;
  padding-top: 28px;
}

.org-chart ul::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  height: 14px;
  border-left: 2px solid var(--org-line);
}

.org-chart li {
  position: relative;
  padding: 0 6px;
  text-align: center;
}

.org-chart ul > li::before,
.org-chart ul > li::after {
  content: "";
  position: absolute;
  top: -14px;
  width: 50%;
  height: 14px;
  border-top: 2px solid var(--org-line);
}

.org-chart ul > li::before {
  right: 50%;
}

.org-chart ul > li::after {
  left: 50%;
  border-left: 2px solid var(--org-line);
}

.org-chart ul > li:first-child::before,
.org-chart ul > li:last-child::after {
  border-top: 0;
}

.org-chart ul > li:only-child::before,
.org-chart ul > li:only-child::after {
  display: none;
}

.org-node,
.org-card {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 100px;
  min-height: 48px;
  background: var(--org-surface);
  border: 1px solid var(--org-border);
  border-radius: 8px;
  box-shadow: 0 8px 18px rgba(23, 32, 51, 0.08);
}

.org-node {
  padding: 9px 10px;
  font-size: 13px;
  font-weight: 700;
}

.org-node--top {
  color: #FFFFFF;
  background: var(--org-blue);
  border-color: var(--org-blue);
}

.org-node--dept {
  border-color: rgba(22, 160, 133, 0.45);
}

.org-node--team {
  min-width: 90px;
  min-height: 42px;
  font-size: 11px;
  color: #3F4C5F;
  background: #FBFCFE;
}

.org-card {
  align-items: stretch;
  width: 126px;
  min-height: 112px;
  padding: 12px;
  gap: 7px;
}

.org-role {
  align-self: center;
  max-width: 100%;
  padding: 3px 8px;
  font-size: 11px;
  font-weight: 700;
  color: #174A80;
  background: #E8F2FF;
  border-radius: 999px;
}

.org-name {
  font-size: 15px;
}

.org-dept {
  font-size: 12px;
  color: var(--org-muted);
}

.org-card--sales .org-role {
  color: #0F5F50;
  background: #E7F7F3;
}

.org-card--dev .org-role {
  color: #5C430A;
  background: #FFF3D6;
}

@media (max-width: 640px) {
  body {
    padding: 16px;
  }

  .org-chart li {
    padding-inline: 5px;
  }

  .org-node {
    min-width: 88px;
    padding: 8px 9px;
    font-size: 11px;
  }

  .org-card {
    width: 116px;
  }
}

@media print {
  .org-scroll {
    overflow: visible;
    background: #FFFFFF;
    border-color: #777777;
  }

  .org-node,
  .org-card {
    color: #111111;
    background: #FFFFFF;
    border-color: #555555;
    box-shadow: none;
  }

  .org-role {
    color: #111111;
    background: #FFFFFF;
    border: 1px solid #777777;
  }
}
// このサンプルではJavaScriptを使用しません。
// 組織図はHTMLのul/li構造とCSSの疑似要素だけで表示しています。

AI用プロンプト

各パターンのプロンプトをコピーしてAIに渡すと、同様の組織図コンポーネントを生成できます。

ChatGPTやClaudeにこのプロンプトを渡すと、同様のコンポーネントをゼロから生成・カスタマイズできます。部署数や役職名、カード内の項目を変更したい場合は、要件を追記して使うのがおすすめです。

※ このプロンプトを使ってもデモとまったく同じ見た目にならない場合があります。AIの解釈や生成タイミングによって差が出ることをご了承ください。

ヒント: React・Vueなど特定のフレームワークで実装したい場合は、プロンプトの末尾に「〇〇を使って実装してください」と追記してください。

Pattern 1 — 基本の縦型組織図

# 組織図(HTML/CSSのみ)作成依頼

## 概要
社内組織図をHTMLとCSSだけで実装してください。
ネストしたul/liで階層構造を持ち、CSSの疑似要素で親子の接続線を描く構成にしてください。

## 要件
- JavaScriptと外部ライブラリは使わない
- 組織図のHTML構造はul/liのネストで表現する
- 代表取締役、営業部、開発部、管理部、各課の3階層を表示する
- 接続線はCSSの::before / ::afterとborderで描く
- CSSが無効でも階層リストとして読める構造にする
- 小画面では横スクロールを許可し、組織図の親子関係を崩さない
- 印刷時にも線とノード境界が見えるように@media printを用意する

## 技術仕様
- HTML / CSS のみで実装
- 外部ライブラリ:なし
- JavaScript:使用しない
- レスポンシブ対応:必要(横スクロール容認)

## 動作詳細
ユーザー操作はありません。
ページ読み込み時点で、静的HTMLとして組織図が表示されるようにしてください。

## 出力形式
HTML・CSSを分けて出力してください。
JavaScript欄には「このサンプルではJavaScriptを使用しません」とコメントで明記してください。

Pattern 2 — カード型ノード

# カード型ノードの組織図(HTML/CSSのみ)作成依頼

## 概要
役職・氏名・部署ラベルを持つカード型ノードの組織図を、HTMLとCSSだけで実装してください。
組織図の階層はul/liで持ち、見た目だけをカード型にしてください。

## 要件
- JavaScriptと外部ライブラリは使わない
- 組織図のHTML構造はul/liのネストで表現する
- 各ノードには役職、氏名、部署ラベルを表示する
- 写真プレースホルダ、人数バッジ、状態バッジは入れない
- 接続線はCSSの::before / ::afterとborderで描く
- 小画面では横スクロールを許可し、親子関係の線を崩さない
- 印刷時にも線とカード境界が見えるように@media printを用意する

## 技術仕様
- HTML / CSS のみで実装
- 外部ライブラリ:なし
- JavaScript:使用しない
- レスポンシブ対応:必要(横スクロール容認)

## 動作詳細
ユーザー操作はありません。
ページ読み込み時点で、静的HTMLとしてカード型の組織図が表示されるようにしてください。

## 出力形式
HTML・CSSを分けて出力してください。
JavaScript欄には「このサンプルではJavaScriptを使用しません」とコメントで明記してください。