Host a Ghost Blog on AWS in 2023 (IV) - Create a Functional Table of Contents
A functional table of contents (TOC) is easy for users to navigate through the long article, but Ghost did not provide a nice out-of-the-box solution. This post is to show you how to build a nice table of contents like you see on the right with easy tweaks.
Besides, for those who are interested in building the blog, the prior 3 parts are the go-to reference:
1 Problem Statement
Ghost in fact introduces a simply table of contents in the official tutorial:
![](https://ghost.org/tutorials/content/images/2022/05/toc.jpg)
The TOC can be inserted into your theme, but in most cases they are not user friendly and pretty:
- Everything is underlined
- It is too close to the content
- It is overlapped with meta data like author, tags
- It is overlapped with wide or full images
![](https://cdn.jsdelivr.net/gh/BulletTech2021/Pics/img/1_V/toc_bad.png)
2 Fix
Suppose that you have followed the example shared by Ghost official document, then the default.hbs
and post.hbs
have been updated and the Tocbot code has been added. Please do it if you have not so that at least there is a TOC no matter how bad it is :p
Now what we need to fix is the style of the TOC by editing the code in default.hbs
.
2.1 Style
Firstly, go to the default.hbs
file, below CSS code is inserted above {{ghost_head}}
to set proper styles.
<style>
.gh-content {
position: relative;
z-index: 1;
}
/*-- Remove underline in the TOC text */
.gh-content a {
text-decoration: none;
}
.gh-content img{
position: relative;
z-index: 2;
}
.gh-toc > .toc-list {
position: relative;
}
.toc-list {
overflow: hidden;
list-style: none;
left: 20%;
}
@media (min-width: 1300px) {
.gh-sidebar {
position: absolute;
top: 0;
bottom: 0;
margin-top: 4vmin;
/* grid-column: wide-start / main-start; Place the TOC to the left of the content */
grid-column: main-end / wide-end ; /* Place the TOC to the right of the content */
}
.gh-toc {
position: sticky; /* On larger screens, TOC will stay in the same spot on the page */
top: 4vmin;
/*-- Send the TOC to the back, in case it is overlapped with images */
z-index: 1;
}
}
/*-- Hide TOC on mobile devices */
@media (max-width: 768px) {
.gh-toc {
display: none;
}
}
.gh-toc .is-active-link::before {
background-color: var(--ghost-accent-color); /* Defines TOC accent color based on Accent color set in Ghost Admin */
}
</style>
z-index
is used to control the position of each element on the Z axis, in the above setting, images are placed on the front and the main content and TOC are behind it so that TOC does not float over wide or full images. Below snippet is added to remove the underline of text in the TOC:
/*-- Remove underline in the TOC text */
.gh-content a {
text-decoration: none;
}
Then, grid-column: main-end / wide-end
is used to put the TOC on the right, please note that if you should use grid-column: wide-start / main-start
if you still expect the TOC on the left.
@media (min-width: 1300px) {
.gh-sidebar {
position: absolute;
top: 0;
bottom: 0;
margin-top: 4vmin;
/* grid-column: wide-start / main-start; Place the TOC to the left of the content */
grid-column: main-end / wide-end ; /* Place the TOC to the right of the content */
}
.gh-toc {
position: sticky; /* On larger screens, TOC will stay in the same spot on the page */
top: 4vmin;
/*-- Send the TOC to the back, in case it is overlapped with images */
}
}
Next, because the TOC is now on the right, and pretty close to the content, left: 30%
is used to add margin so that it is a bit distant to the content. If your TOC is on the left, you should consider tweaking the parameter right
with proper margin.
.toc-list {
overflow: hidden;
list-style: none;
left: 30%;
}
Also, below code is used to hide the TOC on small devices as the TOC is not able to hover side by side and so it is unnecessary.
/*-- Hide TOC on small devices */
@media (max-width: 768px) {
.gh-toc {
display: none;
}
}
2.2 Function
Now go to the end of the default.hbs
and below code is inserted above {{ghost_foot}}
.
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.12.3/tocbot.min.js"></script>
{{! Initialize Tocbot after you load the script }}
<script>
tocbot.init({
// Where to render the table of contents.
tocSelector: '.gh-toc',
// Where to grab the headings to build the table of contents.
contentSelector: '.gh-content',
// Which headings to grab inside of the contentSelector element.
headingSelector: 'h2, h3, h4',
// Ensure correct positioning
hasInnerContainers: true,
orderedList: false,
});
</script>
orderedList: false
is added to remove the order a, b, c, d
in the TOC, as you can order the headers yourself if necessary.
3 Conclusion
With above simple tweak, the issues of the primitive TOC have been fixed perfectly, hope it helps you to prettify your Ghost website with a functional TOC.
Appendix
In-depth Ghost Tutorials
![](https://ghost.org/tutorials/content/images/2022/05/ghost-tutorials-cover.png)