[CSS] 上下関係・親子関係を表した系図を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」を変更することで、図全体のサイズ感を調整することができます
矢印と集合線の描画について
- 図の矢印は「linear-gradient」を使って背景画像として描画しています
- 子要素の数が増減したときにもなるべくCSSを変えないようにするため、矢印と、矢印をまとめる集合線をそれぞれ分解して描画しています
矢印の描画
.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疑似要素に矢印と縦線だけ描いて線の集合部分を省くことで、「左端の要素は右に線を伸ばす」「右端の要素は左に線を伸ばす」といった要素による場合分けをしないで済むようにしています
集合線の描画
.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>
- 図の段を増やしたい場合は、ddタグの中に「genealogy」クラス一式をそのまま入れ込みます
.genealogy .genealogy {
position: absolute;
top: -0.2em;
left: 50%;
transform: translateX(-50%);
margin: 0px;
}
- 段を増やしたとき(入れ子になったとき)の位置調整用のスタイルです
- 「position: absolute;」と「transform: translateX(-50%);」を使って中央揃えにし、枠線の太さ「-0.2em」分だけ「top」の位置をずらしています
ご質問など受け付けています
記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。
ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。