2015-08-13 7 views
7

Ich versuche, eine vertikale baumartige Struktur mit HTML und CSS zu zeichnen. Ich habe es bis zu einem gewissen Grad getan.Vertikaler Baum mit CSS und HTML

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 meinem Fall kann ein Knoten maximal 2 Kinder haben, nicht mehr als das. Ich habe es für den ersten Kindknoten funktioniert. Im Falle des zweiten Kindes, bekomme ich die vertikale Linie nicht zu 100% (bis zum Elternknoten).

Ich habe versucht, ein paar Verbesserungen, aber keiner von ihnen funktioniert. Was kann ich in mein CSS ändern, damit alle Knoten verbunden werden und wie ein Baum aussieht?

Ist es möglich, mit CSS selbst zu tun? oder ist es möglich, etwas Javascript hinzuzufügen?

Antwort

2

Wenn Sie eine begrenzte Anzahl von Möglichkeiten haben, und nicht auf der Suche nach etwas sehr dynamisch, eine Sache, die Sie tun können, ist Klassen hinzufügen mit verschiedenen top und height für Ihre :after pseudo element und gelten Klassen in Ihrem HTML Sie li Elemente je nachdem, was jeder brauchen. Etwas, dass zum Beispiel:

.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:

Handhabung :after pseudo-elements ist dynamisch nicht so einfach (zumindest nicht für mich ...). Es gibt nicht wirklich eine Möglichkeit, sie direkt zu behandeln, Sie müssen ihr tatsächliches Element durchlaufen, und selbst dann müssen Sie mit CSS arbeiten. Also eine dynamische Lösung mit :after wäre nicht der beste Ansatz, denke ich.

Aber Sie könnten sie durch span ersetzen und mit jQuery arbeiten. Dies gibt Ihnen eine relativ kleine und einfache Lösung. Fügen Sie zunächst eine Spanne zu jeweils einem Element:

<li><a href="#">Child</a> <span></span>  
<li><a href="#">Grand Child</a><span></span> 

Dann in Ihrem CSS ersetzen: nach mit> Spannweite:

.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; 
} 

Und Sie gehen durch jede dieser span und einige Berechnungen einstellen height und top je nach 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/

Die äquivalente Lösung in Plain javascript wäre viel länger, ich denke, es ist die Art von Situation, wo jQuery kann viel Zeit sparen.

+0

Danke Julien. Das Problem hierbei ist, dass die Tiefe jedes Knotens beliebig sein kann. Ich kann keine zweistufigen, dreistufigen Klassen definieren, da es 99 Schritte oder n Schritte geben kann. Gibt es also eine Möglichkeit, diese Pseudoklassen-Funktionalität dynamisch zu definieren? – Naga

+0

Soweit ich weiß, ist das dynamische Arbeiten mit Pseudoklassen nicht so einfach. Ich würde mit jQuery gehen, wenn Sie etwas flexibler möchten. Siehe Bearbeiten. –

+0

Ich habe versucht, mit der jQuery, die Sie gegeben haben. Wenn ich einen Knoten in der Liste dynamisch hinzufüge/entferne. Die Linien kommen nicht in der richtigen Höhe, selbst nach dem Neuzeichnen der Linien. https: // jsfiddle.net/qvnw6510/10/ (In jfiddle, die Funktion wird nicht aufgerufen, wenn ich Knoten hinzufügen. Sie können den Code in Ihrem Computer überprüfen.) Ich habe versucht, es zu debuggen, konnte aber nicht lösen. Ich finde die Berechnung der Höhe funktioniert nicht wie erwartet. – Naga