Two Wrongs

(don't make a right)

Draw a Tree Structure With Only CSS

by ~kqr

Sometimes you have data in a tree structure. Common candidates are hierarchies in a company, module architecture in a system or files on disk. It would be really nice to be able to generate an HTML page with this data neatly rendered so as to actually look like a tree structure. In other words, we'll be shooting for something like this*:

a tree structure drawn with CSS

That's actually drawn with only CSS, using the pseudo-elements ::before and ::after. We start with a simple HTML list.

<div class="clt">
  <ul>
    <li>
      Fruit
      <ul>
        <li>
          Red
          <ul>
            <li>Cherry</li>
            <li>Strawberry</li>
          </ul>
        </li>
        <li>
          Yellow
          <ul>
            <li>Banana</li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      Meat
      <ul>
        <li>Beef</li>
        <li>Pork</li>
      </ul>
    </li>
  </ul>
 </div>

With this out of the way, let's get into the CSS. First we need to set up the list and container so it doesn't interfere with our tree drawing.

.clt, .clt ul, .clt li {
     position: relative;
}

.clt ul {
    list-style: none;
    padding-left: 32px;
}

Then we take our pseudo-elements, make sure they are empty and move them to the left of the list elements.

.clt li::before, .clt li::after {
    content: "";
    position: absolute;
    left: -12px;
}

The ::before pseudo-element is used to draw the horizontal lines.

.clt li::before {
    border-top: 1px solid #000;
    top: 9px;
    width: 8px;
    height: 0;
}

...and the vertical lines use the ::after pseudo-element.

.clt li::after {
    border-left: 1px solid #000;
    height: 100%;
    width: 0px;
    top: 2px;
}

The icing on the cake is that the last item on every level has just a very short line leading to it, and nothing further. This makes it look very nice.

.clt ul > li:last-child::after {
    height: 8px;
}

And that's it! I think it's fascinating something like that is possible.


  1. * If the tree I used as an example in this post looks familiar, it's because it's been used by someone else to illustrate efficient storage of trees in relational databases. I stole it from there.

  2. If this doesn't highlight one of the problems with the HTML format, I don't know what does.

If you enjoyed this article, you might like others tagged with