I Am trying to draw a vertical tree like structure with HTML and CSS. I have done it to some extent.
Fiddle
<!--
We will create a family tree using just CSS(3)
The markup will be simple nested lists
-->
<div class="tree">
    <ul>
        <li>
            <a href="#">Parent</a>
            <ul>
                <li><a href="#">Child</a>
                    <ul>
                        <li><a href="#">Grand Child</a></li>
                    </ul>
                </li>
                <li>
                    <a href="#">Child</a>
                    <ul>
                        <li><a href="#">Grand Child</a></li>
                        <li><a href="#">Grand Child</a>
                            <ul>
                                <li><a href="#">Great Grand Child</a></li>
                                <li><a href="#">Great Grand Child</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>
In my case, a node can have maximum 2 childs, not more than that. I have got it working for the first child node. In case of second child, am not getting the vertical line to 100%(till its parent node).
I have tried doing some tweaks but none of them worked. What could I change to my CSS, so it will get all the nodes connected and looks like a tree?
Is it possible to do with CSS itself? or is it possible to by adding some javascript?
If you have a limited set of possibilities and not looking for something very dynamic, one thing you could do is add classes with different top and height for your :after pseudo element and apply classes in your html to you li elements depending on what each need. Something like that for example:
.tree li::after{
    content: '';
    position: absolute; top: 0;
    width: 3%; height: 50px;
    right: auto; left: -2.5%;
    border-bottom: 1px solid #ccc;
    border-left: 1px solid #ccc;
    border-radius: 0 0 0 5px;
    -webkit-border-radius: 0 0 0 5px;
    -moz-border-radius: 0 0 0 5px;
}
.tree li.two-step::after{
    top: -100px;
    height: 150px;
}
.tree li.three-step::after{
    top: -180px;
    height: 230px;
}
https://jsfiddle.net/g2ue3wL5/1/
EDIT:
Handling :after pseudo-elements dynamically isn't so easy (at least not for me...). There's not really a way to handle them directly, you have to go through their actual element, and even then you need to work with CSS. So a dynamic solution with :after wouldn't be the best approach I think.
But you could replace them with span, and work with jQuery. This gives you a relatively small and easy solution. First, add a span to each a element:
<li><a href="#">Child</a> <span></span>    
<li><a href="#">Grand Child</a><span></span>
Then, in your CSS replace :after with > span:
.tree li > span {
    content:'';
    position: absolute;
    top: 0;
    width: 3%;
    height: 50px;
    right: auto;
    left: -2.5%;
    border-bottom: 1px solid #ccc;
    border-left: 1px solid #ccc;
    border-radius: 0 0 0 5px;
    -webkit-border-radius: 0 0 0 5px;
    -moz-border-radius: 0 0 0 5px;
}
And you go through each of these span and make some calculations to set height and top depending on the parent:
$('.tree li > span').each(function () {
    var thisNewTop = $(this).closest('ul').offset().top - $(this).offset().top; 
    var thisNewHeight = $(this).offset().top - $(this).closest('ul').offset().top + 50;
    $(this).css({
        top: thisNewTop,
        height: thisNewHeight
    });
});
https://jsfiddle.net/g2ue3wL5/3/
The equivalent solution in plain javascript would be much longer, I think it's the kind of situation where jQuery can save a lot of time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With