alt:"screenshot of the table of contents for a blog post (this blog post, in fact). it's been styled so that the output resembles the hierarchical file system output from the shell program 'tree.'"
tags:
- reference
- software
---
I have a shiny new Table of Contents (hereafter ToC) section for some of my posts (like this one)! And for fun and profit, it's styled like the output of [`tree`](https://en.wikipedia.org/wiki/Tree_(command)). I want to lay out the CSS I used for this. Fair warning, there's some hyper-specific border widths and positioning that *probably* should be a `calc()` function of some kind.
I drew inspiration from this [StackOverflow issue regarding tree styling for lists](https://stackoverflow.com/questions/14423671/best-method-for-displaying-a-tree-list-using-css-only-no-images-or-js-example).
## `tree`
Just for reference, here's some sample `tree` output:
```txt
.
├── footer.njk
├── head-content.njk
├── header.njk
├── layouts
│ ├── base.njk
│ ├── page-lists.njk
│ ├── page.njk
│ ├── post.njk
│ ├── post-with-toc.njk
│ └── tag-redirect.njk
├── pagination.njk
├── postlist.njk
└── webring.njk
```
(You'll note that there are gaps between the verticals of each line. That's due to the line-height on the page, but in a standard terminal those vertical lines would be contiguous.)
Despite referencing a StackOverflow issue above, I never like to just copy-paste a chunk of StackOverflow code into place. I don't like extraneous CSS, and sometimes there's stuff mixed in there that just isn't necessary. Let's build from the ground up.
### remove styling that will be in the way
By default, my lists have a lot of space around them for legibility when reading longer list items. We'll be accomplishing the vertical bars with borders here, so it's critical we not have any block-oriented spacing on `<ol>`s and `<li>`s. We're also going to take the numeric `list-style` off.
The `tree`-like structure will be accomplished with both symbols (stolen directly from the tree output) and borders. Let's throw some borders on.
```css
#tocli{
border-left:.095remsolidvar(--color-pink);
}
```

Those are super off. First, they're tabbed too far in to the left; second, there's *no* space between the border and the list item. We're going to fix the first thing by removing left margins on the `<ol>`s. The second is where we pull in the most critical piece of infrastructure.
Notably, without additional positioning, the bars will be spaced away from the border. We want them to overlap perfectly.


### adjust left margins
Right now, the vertical lines don't nest nicely underneath the level above. Let's change our margins. I also adjusted the line height very slightly, because I noticed on some levels of magnification that the tree line leader characters weren't actually meeting.
```css
#tocli{
margin-left:1.5rem;
line-height:1.15;
}
```

### fix those pesky last children
You've probably noticed that the last children in the tree output had a bend rather than the T-shape we've been using. We'll want to remove the border from the last children and change the character we're using.

### but what about really, really, really, really, REALLY long headers?
What about line wrapping? It looks pretty bad right now.

(And for the record, this happens for middle children too, it's not just a last child issue.)
