CSS3, HTML, HTML5, Programming, Web Development

Example Pure CSS Family Tree Markup

Family Tree Hierarchy
Family Tree Hierarchy

There are a number of ways to generate and display hierarchical data in a visually appealing tree-like structure. The best way, of course, is to not have to rely on external libraries, and to deal with pure markup.

I’ve been looking at various solutions, and I’m posting below some pure CSS/HTML markup that I found on stack overflow and modified to show a family-tree like structure like the example picture above.

Specifically, the CSS markup in the test page works by styling nested unordered lists. You can add a new level to the hierarchy of your tree by adding a new unordered list to the <li of an existing list.

Tree Features

I won’t go into the details of the CSS markup, but it’s completely flexible and under your control to alter as you need since it is pure CSS and does not rely on any external libraries to work.

The tree uses thin 1 pixel thick lines to connect the nodes of the tree along with rounded borders. When you mouse-over a node of the tree, it will highlight the associated sub-nodes, making it easy to see relationships in the tree. It’s also nice that you can start with more than one top parent node.

Then within each tree node (unordered list <li tag), one or more family members’ information is encapsulated within a div and a span tag. The div can be used to hold two span tags to show father and mother information. Then you can show a blue colored area using a span with the male class or a pink colored area with the female class.

This is obviously just an example of what you can do with this markup. It should be useful for rendering any type of hierarchical data (family trees, employee hierarchies, etc.)

Tree Problems

The main problem that happens is the wrapping that happens if your tree grows to be too wide. The tree then wraps its branches and looks unclear and messy. To deal with this issue, you can add some JavaScript to dynamically set the width of the <div that hosts the hierarchy. There is no clean way that I’ve found yet that can determine the maximum width that will be needed, so you’ll need to guesstimate the maximum for your JavaScript to use.

The Example Code:

Here is the markup that will render the example family tree shown in the picture at the start of this post.

<html>
<head >
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Test Family Tree</title>
<!-- I found and adapted this css code from: https://stackoverflow.com/questions/38192074/family-tree-css -->
<!-- There is also an example on codepen.io at: http://codepen.io/Pestov/pen/BLpgm -->
<!-- I am not sure who the original creator is -->

<style>
* {
margin: 0;
padding: 0;
font-family:sans-serif,Arial;
font-size:10pt;
}
.tree {
white-space: nowrap;
min-width: 800px;
min-height:500px;
}
.tree ul {
padding-top: 20px;
position: relative;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
.tree li {
float: left;
text-align: center;
list-style-type: none;
position: relative;
padding: 20px 5px 0 5px;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
/*We will use ::before and ::after to draw the connectors*/
.tree li::before, .tree li::after {
content: '';
position: absolute;
top: 0;
right: 50%;
border-top: 1px solid #ccc;
width: 50%;
height: 20px;
}
.tree li::after {
right: auto;
left: 50%;
border-left: 1px solid #ccc;
}
/*We need to remove left-right connectors from elements without any siblings*/
.tree li:only-child::after, .tree li:only-child::before {
display: none;
}
/*Remove space from the top of single children*/
.tree li:only-child {
padding-top: 0;
}
/*Remove left connector from first child and right connector from last child*/
.tree li:first-child::before, .tree li:last-child::after {
border: 0 none;
}
/*Adding back the vertical connector to the last nodes*/
.tree li:last-child::before {
border-right: 1px solid #ccc;
border-radius: 0 5px 0 0;
-webkit-border-radius: 0 5px 0 0;
-moz-border-radius: 0 5px 0 0;
}
.tree li:first-child::after {
border-radius: 5px 0 0 0;
-webkit-border-radius: 5px 0 0 0;
-moz-border-radius: 5px 0 0 0;
}
/*Time to add downward connectors from parents*/
.tree ul ul::before {
content: '';
position: absolute;
top: 0;
left: 50%;
border-left: 1px solid #ccc;
width: 0;
height: 20px;
}
.tree li div {
border: 1px solid #ccc;
padding: 5px 10px;
text-decoration: none;
color: #666;
font-family: arial, verdana, tahoma;
font-size: 11px;
display: inline-block;
min-width: 80px;
min-height: 30px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
.tree li div .male {
background-color:lightblue;
display: inline-block;
width:90px;
padding:10px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
.tree li div .female {
background-color:lightpink;
display: inline-block;
width:90px;
padding:10px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
.tree li div .spacer {
background-color:lightblue;
display: inline-block;
width:10px;
}
/*Time for some hover effects*/
/*We will apply the hover effect the the lineage of the element also*/
.tree li div:hover, .tree li div:hover + ul li div {
background: #c8e4f8;
color: #000;
border: 1px solid #94a0b4;
}
/*Connector styles on hover*/
.tree li div:hover + ul li::after,
.tree li div:hover + ul li::before,
.tree li div:hover + ul::before,
.tree li div:hover + ul ul::before {
border-color: #94a0b4;
}
</style>

</head>
<body>

<form id="form1">

<div class="tree" id="FamilyTreeDiv">

<ul>

<li>
<div><span class="male">Joe Mighty
1601 - 1681</span></div>
</li>


<li>
<div><span class="female">Sue Mighty
1607 - 1685</span><span class="spacer"></span><span class="male">Jim Snow
1633 - 1697</span></div>


<ul>

<li>

<div><span class="male">Sam Snow
1631 - 1695</span><span class="spacer"></span><span class="female">Lily Sight
1633 - 1697</span></div>


<ul>

<li>
<div><span class="male">Ralf Snow
1651 - </span></div>
</li>


<li>
<div><span class="female">Brie Snow
1653 - </span></div>
</li>

</ul>

</li>


<li>

<div><span class="male">Jim Snow
1633 - 1697</span><span class="spacer"></span><span class="female">Zoe Blue
1633 - 1697</span></div>


<ul>

<li>
<div><span class="male">Ralf Snow
1651 - </span><span class="spacer"></span><span class="female">Sally Bern
1653 - </span></div>


<ul>

<li>
<div><span class="female">Magna Snow
1679 - </span></div>
</li>

</ul>
</li>


<li>
<div><span class="female">Brie Snow
1653 - </span></div>
</li>

</ul>

</li>


<li>
<div><span class="male">John Snow
1635 - 1699</span></div>
</li>

</ul>
</li>

</ul>

</div>

</form>

</body>
</html>

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s