Table of Contents
To add a table of contents in Hugo you can add the built in variable {{ .TableOfContent }}
to a template file, typically the template for regular pages, single.html
.
To turn it on or off for a given page first make it condition to be met:
{{ if .Params.toc }}
{{ .TableOfContents }}
{{ end }}
Then just add the param toc
to the frontmatter of pages you want a table of contents to be generated:
toc: true
Multi columns
This generates an unordered list of links to the headings inside a nav
element:
<nav id="TableOfContents">
<ul>
<li><a href="#heading-text-1">heading-text-1</a></li>
<li><a href="#heading-text-2">heading-text-2</a></li>
<li><a href="#heading-text-3">heading-text-3</a></li>
</ul>
</nav>
Making the columns responsive
The number of list items varies depending on the number of headings on each page. If there are only a few, say 3 or 4, you might prefer a straight vertical list of headings. Using the Every Layout technique a query selector can be created using the nth-last-child()
selector to layout multiple columns only when there is a certain number of list items (ie. generated from headings).
Firstly layout the columns:
#TableOfContents ul {
columns: 3 15em;
column-gap: 1em;
}
The first line, columns: 3 15em;
creates a maximum of 3 columns that are at least 15ems wide.
#TableOfContents ul > li {
column-span: all;
}
This part makes all those list items span fully across all 3 columns.
The next part does the opposite using the nth-child
pseudo-selector. Using :nth-last-child
means counting from the end of a list rather than the beginning. How about the n+5
bit? If we used just li:nth-last-child(5)
we would only select one item, the fifth from the end of the list. Using n+5
means selecting the fifth element and all those before it.
If there are 5 or fewer items none will be selected.
The final line counts forwards from that fifth-from-the-end item using the general sibling combinator ~
. These two selectors mean all list items are selected.
#TableOfContents li:nth-last-child(n+5), /* selects backwards from the fifth last item */
#TableOfContents li:nth-last-child(n+5) ~ li { /* selects forwards from the fifth last item */
column-span: none;
}