Pure CSS Tree with Borders

Pure css tree with borders

Simple with Multi-level Depth Support

UPDATED: Tweaked to accommodate hover

No extra HTML needed, no having to limit depth because of css selector chaining, as it supports any number of levels deep without having to adjust your css at all for those levels (no keeping track of "padding" to set on the next level deep).

This works well with only a two minor limitations (which I don't believe will factor into affecting you).

See fiddle demo.

Add a position: relative to your ul.tree, but keep all the child elements the default static position. Then change/add the following css:

ul.tree a {
display: block;
height:30px;
line-height: 30px;
padding-left: 15px;
}

/* this is making our bottom border, but sizing off the .tree ul width */
ul.tree a:before {
content: '';
height: 30px; /* match your <a> height */
position: absolute;
left: 0;
right: 0;
z-index: -1;
border-bottom-width: 1px;
border-bottom-color: lightgray;
border-bottom-style: solid;
}

ul.tree a + ul {
padding-left: 15px; /* this is your spacing for each level */
}

ul.tree a:hover:before {
background-color: #DDDDDD;
}

The limitations are that no child elements can have a position set and we are using a pseudo-element (which means it cannot be used for some other feature, but that is probably not an issue either).

Is it possible to make a pure CSS Tree diagram?

Try the code below, it's pure CSS and no JS/jQuery (which IMO is way more compatible), works by manipulating borders and spacing.

Works on FF/Chrome & IE. Enjoy :-)

.parent a,
li {
font-size: 22px;
color: #000;
font-family: "Source Sans Pro", sans-serif;
}
.child a,
li {
font-size: 18px;
color: #000;
}
.subchild a,
li {
font-size: 18px;
color: #888888;
}
.s2child a,
li {
font-size: 16px;
color: #ccc;
}
.tree,
.tree ul {
list-style-type: none;
margin-left: 0 0 0 10px;
padding: 0;
position: relative;
overflow: hidden;
}
.tree li {
margin: 0 0 0 15px;
padding: 0 12px 0 20px;
position: relative;
}
.tree li::before,
.tree li::after {
content: '';
position: absolute;
left: 0;
}
/* horizontal line on inner list items */
.tree li::before {
border-top: 2px solid #000;
top: 14px;
width: 15px;
height: 0;
}
/* vertical line on list items */
.tree li:after {
border-left: 2px solid #000;
height: 100%;
width: 0px;
top: -5px;
}
/* lower line on list items from the first level because they don't have parents */
.tree > li::after {
top: 15px;
}
/* hide line from the last of the first level list items */
.tree > li:last-child::after {
display: none;
}
/* hide line from before the Home or starting page or first element */
.tree > li:first-child::before {
display: none;
}
.tree ul:last-child li:last-child:after {
height: 20px;
}
.tree a:hover {
color: red;
font-weight: 500;
text-shadow: 1px 2px 2px #F3F3F3;
}
<!doctype html><html>
<head> <meta charset="utf-8"> <title>Pure CSS Tree</title> <link href="tree.css" rel="stylesheet" type="text/css"></head>
<body> <ul class="tree"> <li class="parent"><a href="#">Grand Parent</a> <ul> <li class="child"><a href="#">Parent</a> </li> <li class="child"><a href="#">Parent</a> <ul> <li class="subchild"><a href="#">Child</a> <ul> <li class="s2child"><a href="#">Grand Child</a> </li> <li class="s2child"><a href="#">Grand Child</a> </li> <li class="s2child"><a href="#">Grand Child</a> </li> <li class="s2child"><a href="#">Grand Child</a> </li> <li class="last s2child"><a href="#">Grand Child</a> </li> </ul> </li> <li class="subchild"><a href="#">Child</a> <ul> <li class="s2child"><a href="#">Grand Child</a> </li> <li class="s2child"><a href="#">Grand Child</a> </li> </ul> </li> </ul> </li> <li class="child"><a href="#">Parent</a> </li> </ul> </li> </ul>
</body>
</html>

Family tree hierarchy with Pure CSS using divs

First, try using more semantic tags, in the example <main>, <section>, <figure>, and <figcaption> were used instead of <div> and <span>. It doesn't make the HTML invalid if you only use <div> and <span> but it'll hold less meaning and there's a greater chance of errors being overlooked.

display: table/table-row/table-cell was assigned to <main>/<section>/<figure> respectively. Using <table> for layout is highly discouraged, but using other tags that behave like a <table> is ok. In the example, the table-like layout is 3 rows (one row for each generation) and 5 columns. The only borders that are visible are actually the lines that connect "leaves" to each other (as spouses or siblings). For demonstration purposes I added a little JavaScript -- just click anywhere to toggle the invisible borders off and on.

Further details are commented in the example below

<!DOCTYPE html>
<html>

<head>
<title>Family Tree</title>
<link rel="shortcut icon" href="./img/family-tree.png" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="./css/style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=My+Soul&family=Sacramento&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
}

/*
Default font-size is referenced here
Any rem used elsewhere will be directly referenced to this font-size
Default is dynamic -- whenever window is resized, it will adjust to width
if it is bigger than height and vice versa.
In turn, anything in rem will also adjust 2.5vmax === 1rem
*/
html {
font: 2.5vmax/1.5 Sacramento;
}

body {
padding-bottom: 12px;
}

/*
As a <table>, main will adhere to what each column is in width. this
behavior allows it to scale to the width of viewport (window).
*/
main {
display: table;
table-layout: fixed;
width: 100%;
background: transparent;
}

h1 {
display: table-caption;
margin: 10px auto;
padding-top: 10px;
font-family: 'My Soul';
font-size: 2.6rem;
text-align: center;
}

/*
As a <tr>, it automatically holds it's children in a solid row
*/
section {
display: table-row;
background: transparent;
}

/*
As a <td>, padding, vertical-align, width, etc are handled so each one is
uniformly the same height and content is evenly positioned.
*/
figure,
.cell {
display: table-cell;
width: 20%;
background: transparent;
}

img {
width: 7.5em;
height: 7.5rem;
border: solid 3px #606f46;
border-radius: 100%;
box-shadow: 4px 4px 13px #222;
}

figcaption {
width: min-content;
margin-top: -5px;
padding: 10px;
border-style: solid;
border-color: #606f46;
border-radius: 30px 0 30px 0;
background: #beebb3;
box-shadow: 4px 4px 13px #222;
text-align: center;
}

/*
These tags act as empty cells and are placed in-between each "leaf". The majority
of the lines are from their visible borders.
*/
.cell b {
display: block;
position: relative;
z-index: -1;
min-height: 4rem;
}

/*
Applied to .cell between parents -- it connects them
*/
.parents b {
border-top: 6px solid black;
}

/*
Applied to .cell between parents -- it adds a descendant line
*/
.parents b::before {
content: '';
display: block;
position: absolute;
left: 45%;
width: 1px;
height: 8.25rem;
border: 3px solid black;
background: black;
}

/*
Applied to .cell between siblings and the <figure> of any middle children
-- it connects them
*/
.siblings {
border-top: 6px solid black;
}

/*
Applied to .cell to the right of the oldest child and to the left of the
youngest child
*/
.elder,
.baby {
position: relative;
}

/*
Applied to .cell to the right of the oldest child and adds an arrow
*/
.elder::before {
content: '\002b9f';
position: absolute;
left: -1rem;
top: -1.5rem;
font-size: 2rem;
transform: rotate(45deg);
}

/*
Applied to the .cell to the left of the youngest child and adds an arrow
*/
.baby::after {
content: '\002b9f';
position: absolute;
right: -1rem;
top: -1.5rem;
font-size: 2rem;
transform: rotate(-45deg);
}

/*
For demonstration purposes
Styles showLayout(e) toggles on every click (optional)
*/
.show .cell b {
outline: 3px dotted rgba(255, 0, 50, 0.6);
}

.show .cell {
outline: 2px dashed rgba(129, 129, 129, 0.4);
}
</style>
</head>

<body>
<main>
<h1>___Simpson Family Tree___</h1>
<section>
<div class='cell'><b></b></div>
<figure>
<img src="https://i.pinimg.com/originals/e5/4a/bc/e54abc44b68d6b2770696b789b20dafa.png">
<figcaption>Abraham Simpson</figcaption>
</figure>
<div class='cell parents'><b></b></div>
<figure>
<img src='https://comicvine.gamespot.com/a/uploads/square_tiny/11/111746/6556151-mona_simpson.png'>
<figcaption>Mona Simpson</figcaption>
</figure>
<div class='cell'><b></b></div>
</section>
<section>
<div class='cell'><b></b></div>
<div class='cell'><b></b></div>
<figure>
<img src="https://entertainment.time.com/wp-content/uploads/sites/3/2013/05/fictioninfluence_list_homersimpson.jpg">
<figcaption> Homer Simpson </figcaption>
</figure>
<div class='cell parents'><b></b></div>
<figure>
<img src="https://static.wikia.nocookie.net/theultimatesimpsons/images/0/0f/Marge-Simpson-icon.png">
<figcaption>Marge Simpson</figcaption>
</figure>
</section>
<section>
<figure>
<img src="https://openpsychometrics.org/tests/characters/test-resources/pics/S/2.jpg">
<figcaption>Bart Simpson</figcaption>
</figure>
<div class='cell siblings elder'><b></b></div>
<figure class='siblings'>
<img src="https://mella187.github.io/Cartoon-Hero/img/lisa-avatar.jpg">
<figcaption>Lisa Simpson</figcaption>
</figure>
<div class='cell siblings baby'><b></b></div>
<figure>
<img src="https://icons.iconarchive.com/icons/jonathan-rey/simpsons/256/Maggie-Simpson-icon.png">
<figcaption>Maggie Simpson</figcaption>
</figure>
</section>
</main>
<script>
/*
For demonstration purposes - it exposes the borders (optional)
*/
document.querySelector('main').onclick = showLayout;

function showLayout(e) {
this.classList.toggle('show');
}
</script>
</body>

</html>

CSS Vertical line for tree menu

try to add to your CSS

li:last-child {
height: 1px;
}

check demo http://jsbin.com/tigepavemi/1/edit?html,css,output



Related Topics



Leave a reply



Submit