hello, i have ul li html structure and i am trying to make tree horizontally
My Code Below please suggest me how can i do using css ?

<div class="tree"><ul><li><a>SIRE: Cadenza F F58 Barney CA1FF0058</a><ul><li><a>SIRE: HV International F D3106 HVIFD1306 </a></li><li><a>DAM: Amani Elizabeth 5UBFA0550</a><ul><li><a>SIRE: Amani Lancelot 5UBFW1008</a></li><li><a>DAM: Amani F X2073 5UBFX2073</a></li></ul></li></ul></li><li><a>DAM: Dudauman Park F F30 DPKFF0030</a><ul><li><a>SIRE: Dudauman Park Pharoah (ET) DPKFB6009</a><ul><li><a>SIRE: Farmworld War Lord (Imp SAF) (ET) FWBWUL1A</a></li><li><a>DAM: Terra Cotta Thirty Eight (ET) CJVFU0038</a></li></ul></li><li><a>DAM: Dudauman Park F D8012 (ET) DPKFD8012</a><ul><li><a>SIRE: Campbell\'S Tindarra Stately (ET) CTBFZ4203 </a></li><li><a>DAM: Dudauman Park F A5014 (ET) DPKFA5014</a></li></ul></li></ul></li></ul></div>

see attachment output file that i needs.
thankyou.

Dani AI

Generated

Good challenge. Two things make horizontal trees hard: variable label widths and keeping connectors lined up. I agree with @diafol about small screens (you will need a scroll fallback), and with that perfect centering across very uneven branches can require JS. But you can get a solid CSS-only baseline by separating the label from its children and letting flexbox stack children while you draw one vertical trunk per sibling group.

Try this pattern. Keep your UL/LI, but add a label element and a class to LIs that have children. The CSS below draws the elbow from the parent label to a vertical line that spans its children.

<div class="ftree-wrap">
  <ul class="ftree">
    <li class="has-kids">
      <a class="person">SIRE: Cadenza F F58 Barney CA1FF0058</a>
      <ul>
        <li><a class="person">SIRE: HV International F D3106 HVIFD1306</a></li>
        <li class="has-kids">
          <a class="person">DAM: Amani Elizabeth 5UBFA0550</a>
          <ul>
            <li><a class="person">SIRE: Amani Lancelot 5UBFW1008</a></li>
            <li><a class="person">DAM: Amani F X2073 5UBFX2073</a></li>
          </ul>
        </li>
      </ul>
    </li>
    <!-- next branch ... -->
  </ul>
</div>
.ftree-wrap { overflow-x: auto; padding: 8px; }
.ftree, .ftree ul { margin: 0; padding: 0; list-style: none; }
.ftree li { position: relative; }

.ftree ul {
  margin-left: 2.5rem;               /* column width */
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
}

/* vertical trunk for a sibling group */
.ftree ul::before {
  content: "";
  position: absolute;
  left: -1.25rem;
  top: -5px; bottom: -5px;
  border-left: 1px solid #888;
}

/* node label */
.person {
  display: inline-block;
  padding: 2px 6px;
  border: 1px solid #888;
  border-radius: 3px;
  background: #fff;
  color: #333;
}

/* horizontal elbow from parent to trunk */
.has-kids > .person::after {
  content: "";
  position: absolute;
  left: -1.25rem; top: 50%;
  width: 1.25rem;
  border-top: 1px solid #888;
  transform: translateY(-50%);
}

/* print/PDF niceties (DOMPDF): avoid splits, no clipping */
@media print {
  .person { page-break-inside: avoid; }
  .ftree-wrap { overflow: visible; }
}

Tips:

  • When generating HTML in PHP, add the has-kids class to any li that contains a child ul so connectors only draw where needed.
  • For very narrow viewports, keep the tree readable by letting it scroll horizontally rather than squeezing text.

Recommended Answers

All 12 Replies

Well... I can use a little challenge, so I'll see if I can pull it off. My goal is to use no fixed widths or heights. Content should dictate these. Also I might use a nested definition list (dl) for this.

yes you can use DL.
i might not exact idea what you saying.

Using a definition list would be in my opinion sematically more correct then using an unordered list (ul).

Member Avatar for Member #120589

Did you not think about indenting your markup to make it easy for us?

You could do it using inline style, but a fixed CSS may not be exact if the list is dynamic... Javascript would be needed in order to rearrange the display to be exactly what you want.

I'm doing this in between things for you, so have a bit patient.
I have the HTML mark-up in place and will do the CSS, but it is more challenging then I thought in the first place. :)

, @diafol, , i think dl is better but i needs to make it horizontally, and i am trying to fix same as image as i showed in attachment horizontally, i am also tring to do it with css.

Member Avatar for Member #120589

No reason why it can't be done. The issue is what to do with different screen widths.

Using % instead of px or r/em may be advisible. Do you have a max number of generations?
Will you always just have a linear 2 parents per child or will it become more complicated like additional step parent?

You can set the left margin of successive ul li elements easily. You can make elements display block too to ensure their left margins aren't affected by the widths of descendent blocks

@diafol yes, it generates max no of iterations horizontally lets i share css and ul li structure that i am using. this html i sets to pdf using dompdf in php. and i also trying to fix width in tree css for html to pdf.
HTML Code:

<div class="tree">
      <ul>
        <li>
          <a>
            SIRE: Cadenza F F58 Barney CA1FF0058
          </a>
          <ul>
            <li>
              <a>
                SIRE: HV International F D3106 HVIFD1306 
              </a>
            </li>
            <li>
              <a>
                DAM: Amani Elizabeth 5UBFA0550
              </a>
              <ul>
                <li>
                  <a>
                    SIRE: Amani Lancelot 5UBFW1008
                  </a>
                </li>
                <li>
                  <a>
                    DAM: Amani F X2073 5UBFX2073
                  </a>
                </li>
              </ul>
            </li>
          </ul>
        </li>
        <li>
          <a>
            DAM: Dudauman Park F F30 DPKFF0030
          </a>
          <ul>
            <li>
              <a>
                SIRE: Dudauman Park Pharoah (ET) DPKFB6009
              </a>
              <ul>
                <li>
                  <a>
                    SIRE: Farmworld War Lord (Imp SAF) (ET) FWBWUL1A
                  </a>
                </li>
                <li>
                  <a>
                    DAM: Terra Cotta Thirty Eight (ET) CJVFU0038
                  </a>
                </li>
              </ul>
            </li>
            <li>
              <a>
                DAM: Dudauman Park F D8012 (ET) DPKFD8012
              </a>
              <ul>
                <li>
                  <a>
                    SIRE: Campbell'S Tindarra Stately (ET) CTBFZ4203 
                  </a>
                </li>
                <li>
                  <a>
                    DAM: Dudauman Park F A5014 (ET) DPKFA5014
                  </a>
                </li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </div>

CSS Code:

.tree, .tree ul {
                  padding:0;
                  list-style:none;
                  position:relative;
                }

                .tree ul {
                  position:relative;
                  display:inline-block;
                  vertical-align: top;
                }

                .tree ul ul {margin-left:.5em} 

                .tree ul:before {
                  content:"";
                  display:block;
                  width:0;
                  position:absolute;
                  top:10px;
                  margin-top:0px;
                  bottom:0;
                  left:0;
                  border-left:1px solid;

                }

                .tree li {
                  margin:0;
                  padding:1px 1.4em;
                  /*line-height:3em;*/
                  color:#55250A;
                  position:relative;

                  font: normal normal 10px/16px Helvetica, Arial, sans-serif; 
                }
                .tree li a{
                    color:#55250A;
                    font: normal normal 10px/16px Helvetica, Arial, sans-serif;  
                }

                .tree ul li:before {
                  content:"";
                  display:block;
                  width:8px;
                  height:0;
                  border-top:1px solid;
                  position:absolute;
                  top: 0.80em;
                  left:0;
                }

                .tree ul li:last-child:before {
                  background:white;
                  height:auto;
                  top:1em;
                  bottom:0;
                }

Have to agree with @diafol. You have to think of more situations when there is not enough space for a horizontal family tree.

And although a dl is better for semantics, but with the recommended structure of it together with CSS alone, it is not doable to get it the way you want... well as far as I can tell up untill now :)

Member Avatar for Member #120589

OK, had a play with replacing divs with ul/li:

<style>
*, *: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: #eee9dc;
  font: 16px Verdana, sans-serif;
  background: #2e6ba7;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}


#wrapper {
  position: relative;
}

#wrapper li{
  list-style: none;
  position: relative;
  min-height: 60px;
}

#wrapper ul{
    padding-left:0;
}

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

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

#wrapper span {
  display: block;
  min-width: 150px;
  padding: 5px 10px;
  line-height: 20px;
  text-align: center;
  border: 2px solid #eee9dc;
  border-radius: 5px;
  position: absolute;
  left: 0;
  top: 50%;
  margin-top: -15px;
}
</style>

Markup - apologies for additional <span> tags and .sole class

<div id="wrapper"><span>Root</span>
  <ul>
    <li><span>Entry-1</span>
      <ul>
        <li><span>Entry-1-1</span>
          <ul>
            <li class="sole"><span>Entry-1-1-1</span></li>
          </ul>
        </li>
        <li><span>Entry-1-2</span>
          <ul>
            <li class="sole"><span>Entry-1-2-1</span></li>
          </ul>
        </li>
        <li><span>Entry-1-3</span>
          <ul>
            <li class="sole"><span>Entry-1-3-1</span></li>
          </ul>
        </li>
      </ul>
    </li>
    <li><span>Entry-2</span></li>
    <li><span>Entry-3</span>
      <ul>
        <li><span>Entry-3-1</span></li>
        <li><span>Entry-3-2</span></li>
        <li><span>Entry-3-3</span>
          <ul>
            <li><span>Entry-3-3-1</span></li>
            <li><span>Entry-3-3-2</span>
              <ul>
                <li><span>Entry-3-3-2-1</span></li>
                <li><span>Entry-3-3-2-2</span></li>
              </ul>
            </li>
            <li><span>Entry-3-3-3</span></li>
          </ul>
        </li>
        <li><span>Entry-3-4</span></li>
      </ul>
    </li>
    <li><span>Entry-4</span></li>
    <li><span>Entry-5</span></li>
  </ul>
</div>
commented: @diafol: Thank You. +2
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.