Align tree in vertical CSS

2

I'm developing a project where I need to display a family tree. The closest I found was through that topic . But it is displaying horizontally.

How do I change to display vertically?

*, *:before, *:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  min-width: 1200px;
  margin: 0;
  padding: 50px;
  color: #000;
  font: 16px Verdana, sans-serif;
  background: #fff;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#wrapper {
  position: relative;
}

.branch {
  position: relative;
  margin-left: 250px;
}
.branch:before {
  content: "";
  width: 50px;
  border-top: 2px solid #000;
  position: absolute;
  left: -100px;
  top: 50%;
  margin-top: 1px;
}

.entry {
  position: relative;
  min-height: 60px;
}
.entry:before {
  content: "";
  height: 100%;
  border-left: 2px solid #000;
  position: absolute;
  left: -50px;
}
.entry:after {
  content: "";
  width: 50px;
  border-top: 2px solid #000;
  position: absolute;
  left: -50px;
  top: 50%;
  margin-top: 1px;
}
.entry:first-child:before {
  width: 10px;
  height: 50%;
  top: 50%;
  margin-top: 2px;
  border-radius: 10px 0 0 0;
}
.entry:first-child:after {
  height: 10px;
  border-radius: 10px 0 0 0;
}
.entry:last-child:before {
  width: 10px;
  height: 50%;
  border-radius: 0 0 0 10px;
}
.entry:last-child:after {
  height: 10px;
  border-top: none;
  border-bottom: 2px solid #000;
  border-radius: 0 0 0 10px;
  margin-top: -9px;
}
.entry.sole:before {
  display: none;
}
.entry.sole:after {
  width: 50px;
  height: 0;
  margin-top: 1px;
  border-radius: 0;
}

.label {
  display: block;
  min-width: 150px;
  padding: 5px 0px;
  line-height: 20px;
  text-align: center;
  position: absolute;
  left: 0;
  top: 50%;
  margin-top: -15px;
}
<div id="wrapper"><span class="label">Root</span>
  <div class="branch lv1">
    <div class="entry"><span class="label">Entry-1</span>
      <div class="branch lv2">
        <div class="entry"><span class="label">Entry-1-1</span>
          <div class="branch lv3">
            <div class="entry sole"><span class="label">Entry-1-1-1</span></div>
          </div>
        </div>
        <div class="entry"><span class="label">Entry-1-2</span>
          <div class="branch lv3">
            <div class="entry sole"><span class="label">Entry-1-2-1</span></div>
          </div>
        </div>
        <div class="entry"><span class="label">Entry-1-3</span>
          <div class="branch lv3">
            <div class="entry sole"><span class="label">Entry-1-3-1</span></div>
          </div>
        </div>
      </div>
    </div>
    <div class="entry"><span class="label">Entry-2</span></div>
    <div class="entry"><span class="label">Entry-3</span>
      <div class="branch lv2">
        <div class="entry"><span class="label">Entry-3-1</span></div>
        <div class="entry"><span class="label">Entry-3-2</span></div>
        <div class="entry"><span class="label">Entry-3-3</span>
          <div class="branch lv3">
            <div class="entry"><span class="label">Entry-3-3-1</span></div>
            <div class="entry"><span class="label">Entry-3-3-2</span>
              <div class="branch lv4">
                <div class="entry"><span class="label">Entry-3-3-2-1</span></div>
                <div class="entry"><span class="label">Entry-3-3-2-2</span></div>
              </div>
            </div>
            <div class="entry"><span class="label">Entry-3-3-3</span></div>
          </div>
        </div>
        <div class="entry"><span class="label">Entry-3-4</span></div>
      </div>
    </div>
    <div class="entry"><span class="label">Entry-4</span></div>
    <div class="entry"><span class="label">Entry-5</span></div>
  </div>
</div>
    
asked by anonymous 30.06.2015 / 12:39

1 answer

1

Your code is based on absolute placements and margins relative to the array you have now (ie, class label is 50% top of your div parent, class branch has margin-left: 250px , and so on). That is, it was done to be shown from left to right. If you need to do this conversion, I see two ways of doing this:

  • Manually convert

    Basically, you'll rotate your code by 90 degrees. Anything that is positioned relative to the left should be positioned relative to the top, and so forth. It's a bit tedious, repetitive, and with a great chance of getting lost. But as programmers do not like to repeat things , you can appeal to the second option.

  • transform: rotate()

    Since you're going to rotate everything in the arm, what's the problem in letting CSS handle it? If you apply

    #wrapper {
        -webkit-transform: rotate(90deg);
        -moz-transform: rotate(90deg);
        -o-transform: rotate(90deg);
        -ms-transform: rotate(90deg);
        transform: rotate(90deg);
    }
    

    You'll see you're halfway there. The problem is that in this case, you rotate everything within #wrapper , including the text (which I assume you do not want). To solve this problem, simply rotate the text at -90º, or 270º.

     span {
        -webkit-transform: rotate(270deg);
        -moz-transform: rotate(270deg);
        -o-transform: rotate(270deg);
        -ms-transform: rotate(270deg);
        transform: rotate(270deg);
    }
    

    This solves almost 100% of your problem, and you can see it working here . Note that I had to add margin-top:200px; for the word root to appear. Note also that some overlaps appeared between words. This is because of the rotation, and that the code was not built for this orientation. You can play with this pen now, and see how values behave after the transformation is applied. The work to remove these overlaps should not be too large.

  • From here, you choose what kind of work you are going to do. I particularly recommend that you rewrite the code (i.e., follow option 1). Although repetitive, tiring and everything, it is worth learning.

        
    30.06.2015 / 15:38