組織図をcssで書きたいんじゃ

2022年9月29日

テクノロジー プログラミング

eyecatch Webページ制作で、できないことが見当たらない、ユゲタです。 先日ホームページ制作を依頼されているとある会社さんから、組織図を表示して欲しいという要望があり、 その組織図を丁寧にPhotoshopで作って送ってきてくれました。 よくある企業の組織図で、階層も1つだけだったのですが、数が多く横長の図になっていたので、 その画像をスマートフォンで表示する場合は、縦長の画像を用意するしかない(またはそのまま小さい画像を表示)と考えていたらしく、 「ソレ、CSSでできますよ。」と言ってあげると、非常に喜んでもらえたので、 コーディングできない担当者の人は、とかく画像を使いたがりますが、cssを使うと、パケットも軽減できるし、 何より効率的なwebページの構築ができます。 というわけで、今回はそんな組織図をcssで作る方法をソースコードも惜しまずブログで紹介したいと思います。

組織図サンプル

実際の組織図は、企業の内部のものなので、ここで掲載するわけにはいかないので、参考イメージを見せるとこんな感じです。 分かりやすく少ない数で表していますが、右側の数が膨大に増えていく構造ですね。

ソースコード

index.html <link rel='stylesheet' href='organization_chart.css'> <div class='lr-graph flex'> <div class='middle'> <div class='middle-right'> <div class='item'><div class='line'></div></div> </div> </div> <div class='left'> <div class='item'><div class='plate'>--test--</div></div> </div> <div class='middle'> <div class='middle-left'> <div class='item'><div class='line'></div></div> </div> <div class='middle-right'> <div class='item'><div class='line'></div></div> <div class='item'><div class='line'></div></div> <div class='item'><div class='line'></div></div> </div> </div> <div class='right'> <div class='item'><div class='plate'>AAA</div></div> <div class='item'><div class='plate'>BBB</div></div> <div class='item'><div class='plate'>CCC</div></div> </div> </div> organization_chart.css *{ box-sizing: border-box; } .lr-graph{ --size-lr-graph : 500px; --size-left:30%; --size-right:70%; --size-middle-width:50px; --size-item-height:30px; --size-item-mergin : 10px; --color-line: red; } .lr-graph{ width:var(--size-lr-graph); max-width:100%; display:flex; margin:10px auto; } .lr-graph > *{ position:relative; min-height: calc(var(--size-item-height) + var(--size-item-mergin)); } .lr-graph > .left{ text-align:right; } .lr-graph > .right{ text-align:left; } .lr-graph > .left, .lr-graph > .right{ display:block; } .lr-graph > .left{ width:calc(var(--size-left) - var(--size-middle-width) / 2); } .lr-graph > .right{ width:calc(var(--size-right) - var(--size-middle-width) / 2); } .lr-graph > .middle{ width:var(--size-middle-width); } .lr-graph > .middle:first-child{ display:none; } .lr-graph .item{ display:block; height:calc(var(--size-item-height) + var(--size-item-mergin)); line-height:var(--size-item-height); text-align:center; width:100%; position:relative; } .lr-graph .item .plate{ border:1px solid red; width:100%; height:var(--size-item-height); padding:0 10px; border-radius:calc(var(--size-item-height) / 2); position:absolute; top:50%; left:0; transform:translateY(-50%); } /* left */ .lr-graph > .left .item{ position:absolute; top:50%; right:0; transform : translateY(-50%); } .lr-graph > .right .item{ display:block; } /* Middle */ .lr-graph > .middle{ display:flex; } .lr-graph > .middle > *{ width:50%; height:100%; position:relative; } .lr-graph > .middle .middle-left .item{ display:block; width:100%; height:1px; position:absolute; top:50%; left:0; transform:translateY(-50%); background-color:var(--color-line); } .lr-graph > .middle .middle-right .item .line{ position:relative; height:100%; } .lr-graph > .middle .middle-right .item .line::before{ content:''; display:block; width:100%; height:1px; background-color:var(--color-line); position:absolute; top:50%; left:0; transform:translateY(-50%); } .lr-graph > .middle .middle-right .item .line::after{ content:''; display:block; width:1px; height:100%; background-color:var(--color-line); position:absolute; top:0; left:0; } .lr-graph > .middle .middle-right .item:first-child .line::after{ top:50%; height:50%; } .lr-graph > .middle .middle-right .item:last-child .line::after{ top:0%; height:50%; } @media (max-width:500px){ .lr-graph{ flex-wrap:wrap; --size-middle-width:50px; --size-left-mergin : 20px; } .lr-graph > .left{ margin-bottom:var(--size-left-mergin); } .lr-graph > .left, .lr-graph > .right{ width:calc(100% - var(--size-middle-width)) } .lr-graph > .middle:first-child{ display:block; margin-bottom:var(--size-left-mergin); } .lr-graph > .middle:first-child > *{ width:100%; } .lr-graph > .middle:first-child .middle-right .item:last-child .line::after{ top:50%; height:calc(50% + var(--size-left-mergin)); } .lr-graph > .middle > .middle-left::after{ content:''; display:block; width:1px; height:50%; background-color:var(--color-line); position:absolute; top:0; left:0; } }

デモ

--test--
AAA
BBB
CCC
このブログをパソコンで見ている場合は、見ているブラウザの横幅をスマホサイズにしてもらうと、組織図が縦並びになるのが分かりますよ。

ちょびっと解説

こんな風に、レスポンシブデザインにも対応できるCSSで図を表示するのって、きっと多くの人が躊躇してしまうと思いますが、 比較的カンタンにできてしまいます。 今回は、罫線をdivタグをたくさん書いて対応したんですが、もっとシンプルなDOM構造で構築することも可能です。 重要なのは、組織図の中に追加が発生した時に、DOMを追加するだけで対応できるかという事です。 cssで座標指定してしまうと、cssの構造ごと書き直す必要があるので、できるだけ組織構造が変わらず数が変わる場合にちゃんと対応できるようにするというのが重要ですね。 これをもっとシステム化すると、トーナメント表示などでも対応できると思いますよ。 ちなみに、それぞれの名前が入り切らない長い名称が発生した場合は、...(三点リーダー)方式で、はみ出さないように工夫するか、2行までの許容にしてしまうなどの対応でかなり融通が効くようになると思います。

他の対応について

svg形式で構築するというパターンもあり、svgの内部でstyleタグを使って構造体を作ることもできるので、もしかしたらこっちのほうが効率的かもしれませんが、 cssがおぼつかない人がsvgまで覚えるのも大変かと思って、今回はcssのみでの構築を行ってみました。 アイデアは無限大。 できないと諦めてレベルを落とすのではなく、出来る方法をあると信じて突き進むと、他人が喜んでくれる未来が待っていますよ。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。