I wanted a way to add a Table of Contents to WordPress that made the usability of the website much better.

Table of contents

Easy right?

Well, I couldn’t find it in the plugin and so I went searching and decided on the below code.

This Code

I pieced together this Table of Contents from a few different places such as the below.

The PHP


<?php 
// from https://wordpress.org/support/topic/automatically-add-id-to-displayed-post-title/
function auto_id_headings( $content ) {

	$content = preg_replace_callback( '/(\<h[1-3](.*?))\>(.*)(<\/h[1-3]>)/i', function( $matches ) {
		if ( ! stripos( $matches[0], 'id=' ) ) :
			$matches[0] = $matches[1] . $matches[2] . ' id="' . sanitize_title( $matches[3] ) . '">' . $matches[3] . $matches[4];
		endif;
		return $matches[0];
	}, $content );

    return $content;

}
add_filter( 'the_content', 'auto_id_headings' );

wp_register_script( 'Tocbot', 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js', null, null, true );
wp_enqueue_script('Tocbot');

add_action('wp_footer', 'do_tocbot', 999);
function do_tocbot(){ ?>
        <script>
            tocbot.init({
              tocSelector: ".tocbot-toc",
              contentSelector: ".primary-post-content",
              headingSelector: "h2, h3",
              headingsOffset: 30,
              scrollSmoothOffset: -30,
              collapseDepth: 3,
            });
            const targetDiv = document.getElementById("tocbot-toc");
            const btn = document.getElementById("button-toc-toggle");
            targetDiv.style.display = "none";
            btn.onmouseover = function () {
              if (targetDiv.style.display !== "none") {
                targetDiv.style.display = "none";
                //document.body.style.overflow = 'auto';
              } else {
                targetDiv.style.display = "block";
                //document.body.style.overflow = 'hidden';
              }
            };
            btn.onmouseover = function () {
              if (targetDiv.style.display !== "block") {
                targetDiv.style.display = "block";
                //document.body.style.overflow = 'auto';
              }
            };
            btn.onclick = function () {
              if (targetDiv.style.display !== "none") {
                targetDiv.style.display = "none";
                //document.body.style.overflow = 'auto';
              } else {
                targetDiv.style.display = "block";
              }
            };
            document.addEventListener('click', function handleClickOutsideBox(event) {
              //console.log('user clicked: ', event.target);
            
              if (!targetDiv.contains(event.target) && !btn.contains(event.target)) {
                targetDiv.style.display = 'none';
              }
            });
        </script>
<?php }
Code language: PHP (php)

The CSS

.toc-container{
    z-index:12;
}
.toc {
    overflow-y: auto;
}
.toc > .toc-list {
    overflow: hidden;
    position: relative;
}
.toc > .toc-list li {
    list-style: none;
}
.toc-list {
    margin: 0;
    padding-left: 25px;
    overflow-y:auto;
}
a.toc-link {
    height: 100%;
    font-weight: 400;
    text-decoration: none;
}
.is-collapsible {
    overflow: hidden;
    transition: all 300ms ease-in-out;
}
.is-collapsed {
    max-height: 0;
}
.is-position-fixed {
    position: fixed !important;
    top: 0;
}
.is-active-link:hover{
    
}
/*.toc-link::before {
    background-color: #eee;
    content: " ";
    display: inline-block;
    height: inherit;
    left: 0;
    margin-top: -12px;
    position: absolute;
    width: 2px;
}
.is-active-link::before {
    background-color: #000;
}*/
@media only screen and (max-width: 992px) {
    .is-collapsed {
        max-height: none;
    }
}
a.toc-link {
    padding: 7px 0;
    display: block;
    line-height: 1.4;
}
a.toc-link:hover {
    background:#111;
    color:#fff;
}
.is-collapsible a.toc-link, .toc-list .toc-list a.toc-link{
    padding: 5px 15px 5px 35px;
    background: #111;
    border-color: #222;
}
.toc-list a.is-active-link, .toc-list .toc-list a.is-active-link {
    font-weight: 700 !important;
    color:var(--bricks-color-rwiath);
    background:#f4efff;
}
a.toc-link {
    line-height: 1.4;
    color:#fff;
}
.toc-list{
    padding-left:0;
}
.toc-list-item{
    list-style-type:none;
}
.toc-list-item a{
    background:#000;
    border:1px solid #222;
    padding:6px;
}

/* FIXED TOC */
.toc-container{
    /*max-height: 70vh;*/
    display: block;
    width: 100%;
    left: 0;
    right: 0;
    box-shadow: 0px 0px 40px 0px rgb(0 0 0 / 42%);
    background: #000;
    font-size: 1.5rem;
    max-width: 1160px;
    margin: 0 auto;
}
.toc-list-item a{
    background:#000;
    color:#ddd;
}
.tocbot-toc{display:none;}
#tocbot-toc > .toc-list{max-height:60vh;}
.tocbot-toc{border: 10px solid white;border-bottom:0;}
@media only screen and (max-width: 767px) {
    .toc-container{
        max-height:70vh;
        display: block;
        width:100%;
        left:0;
        right:0;
        margin:0;
    }
    .toc-list{width:100%;}
    #tocbot-toc > .toc-list{max-height:60vh;}
    
}
Code language: PHP (php)