ミギムキ

[CSS] 上下関係・親子関係を表した系図をCSSで描きたい

親子関係・上下関係を表した系図

サンプルコード

html

<div class="genealogy"> <dl> <dt>竜騎将バラン</dt> <dd>ラーハルト</dd> <dd>ボラホーン</dd> <dd>ガルダンディー</dd> </dl> </div>
  • 子の数を増やす・減らすときはddタグの数を変更してください

CSS

.genealogy { display: table; position: relative; margin: 0px auto; font-size: 1.5vw; } .genealogy > dl { display: flex; justify-content: center; align-items: center; position: relative; padding: 5em 0px 0px; margin: 0px; } .genealogy > dl::after { position: absolute; top: 3em; left: 6em; right: 6em; height: 2em; background: linear-gradient(to right, #000 0%, #000 100%) top center / 0.2em 100% no-repeat, linear-gradient(to right, #000 0%, #000 100%) bottom left / 100% 0.2em no-repeat; content: ""; } .genealogy > dl > dt, .genealogy > dl > dd { display: flex; justify-content: center; align-items: center; padding: 0.5em; width: 10em; height: 3em; border: 0.2em solid currentColor; box-sizing: border-box; text-align: center; line-height: 1; } .genealogy > dl > dt { position: absolute; top: 0px; left: 50%; transform: translateX(-50%); } .genealogy > dl > dd { position: relative; padding: 0px; margin: 2em 1em 0px; } .genealogy > dl > dd::before { position: absolute; top: -2.4em; left: 0px; width: 100%; height: 2.3em; background: linear-gradient(to right, #000 0%, #000 100%) top center / 0.2em calc(100% - 0.3em) no-repeat, linear-gradient(to top right, transparent 50%, #000 50%) bottom -0.1em left calc(50% - 0.2em + 1px) / 0.4em 1em no-repeat, linear-gradient(to top left, transparent 50%, #000 50%) bottom -0.1em left calc(50% + 0.2em - 1px) / 0.4em 1em no-repeat; overflow: hidden; content: ""; } .genealogy .genealogy { position: absolute; top: -0.2em; left: 50%; transform: translateX(-50%); margin: 0px; }
  • 各要素のサイズは「em」単位で指定しています。「genealogy」クラスの「font-size」を変更することで、図全体のサイズ感を調整することができます

矢印と集合線の描画について

矢印の描画

ddタグにつけた矢印 .genealogy > dl > dd::before { position: absolute; top: -2.4em; left: 0px; width: 100%; height: 2.3em; background: linear-gradient(to right, #000 0%, #000 100%) top center / 0.2em calc(100% - 0.3em) no-repeat, linear-gradient(to top right, transparent 50%, #000 50%) bottom -0.1em left calc(50% - 0.2em + 1px) / 0.4em 1em no-repeat, linear-gradient(to top left, transparent 50%, #000 50%) bottom -0.1em left calc(50% + 0.2em - 1px) / 0.4em 1em no-repeat; overflow: hidden; content: ""; }
  • 各子要素に伸びる矢印線です
  • ddタグのbefore疑似要素に矢印と縦線だけ描いて線の集合部分を省くことで、「左端の要素は右に線を伸ばす」「右端の要素は左に線を伸ばす」といった要素による場合分けをしないで済むようにしています

集合線の描画

dlタグにつけた集合線 .genealogy > dl::after { position: absolute; top: 3em; left: 6em; right: 6em; height: 2em; background: linear-gradient(to right, #000 0%, #000 100%) top center / 0.2em 100% no-repeat, linear-gradient(to right, #000 0%, #000 100%) bottom left / 100% 0.2em no-repeat; content: ""; }
  • 各矢印をまとめる集合線を描きます
  • dlタグのafter要素として、図全体の両端からマージンを取った領域に線を描いています。これで要素の数が増減しても線の長さを微調整する必要がなくなります

段を増やす場合

段を増やした系図 <div class="genealogy"> <dl> <dt>竜騎将バラン</dt> <dd>ラーハルト</dd> <dd> <div class="genealogy"> <dl> <dt>ボラホーン</dt> <dd>ガメゴン</dd> <dd>ガメゴンロード</dd> <dd>ガメゴンレジェンド</dd> </dl> </div> </dd> <dd>ガルダンディー</dd> </dl> </div> .genealogy .genealogy { position: absolute; top: -0.2em; left: 50%; transform: translateX(-50%); margin: 0px; }

ご質問など受け付けています

記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。

ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。