12% off of LTD using this coupon: TWELVEPERCENTOFF. Promo ends on 2 Dec midnight UTC.
Published on Jul 23, 2018

Automatic Table of Contents using Tocbot in Oxygen

Sridhar Katakam

This tutorial provides the steps to automatically display headings inside the content in a sticky (on desktops) sidebar when using Oxygen using Tocbot.

The heading in view will get highlighted in the sidebar when it’s scrolled to and will auto expand and collapse to show subheadings.

Step 1

Install and activate my custom functionality plugin.

Upload tocbot.min.js to wp-content/plugins/my-custom-functionality-master/assets/js.

Let’s load this file before the closing body tag. Inside custom_enqueue_files() of the plugin’s plugin.php, add

if ( is_page( 'tocbot' ) ) {

        plugin_dir_url( __FILE__ ) . 'assets/js/tocbot.min.js',

} // End if().

Replace is_page( 'tocbot' ) with your desired if conditional depending on where you want to use Tocbot.

Step 2

Create/edit your entry (Page or Post etc.).

Add content in the WordPress editor with the text having several H2s and optionally H3s.

Ensure that each heading has a unique ID.

We are going to ask Tocbot to scan for these heading tags.

Here’s some sample HTML for you to get started.

Edit the entry in Oxygen.

By the end of this tutorial, you would have the Structure similar to this:

Add a Section.

Inside the Section, add a 50 50 Columns element.

Change the width of one of your columns – the one in which you would like the auto-generated Table of Contents (left, in this example) to say 30%.

Set a class of sticky to this Div.

Add a Heading element inside the Div and change the text to say, “Quick Links”.

You may want to give this a top and bottom padding of some 20px. Remove the top padding from 992px and below.

Add a Div below it and give it two classes: toc and js-toc.

Tocbot is going to display the TOC inside this element.

Select the wider Div (of the Column) and assign it a class of js-toc-content.

Add WordPress > Dynamic Data > Content inside it. This should show the entry’s content.

Select “Inner Content” and add a Code Block so it sits directly under the Section.


    // echo "hello world!";


.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.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:#54BC4B}

@media only screen and (min-width: 993px) {

  .sticky {
        position: -webkit-sticky;
        position: sticky;
        top: 0;
        align-self: flex-start;


@media only screen and (max-width: 992px) {

  .is-collapsed {
    max-height: none;


.admin-bar .sticky {
    top: 32px;

.sticky:after {
    content: '';
    display: table;

a.toc-link {
    padding: 10px 0;
    display: block;
    line-height: 1.4;

a.toc-link:hover {
    color: #54bc4b;

.is-collapsible a.toc-link {
    padding: 5px 0;

a.toc-link {
    line-height: 1.4;

The first minified part in the above is from here.

The only change in it is the top margin which has been set to -12px from 1px for .toc-link::before.


  // Where to render the table of contents.
  tocSelector: '.js-toc',
  // Where to grab the headings to build the table of contents.
  contentSelector: '.js-toc-content',
  // Which headings to grab inside of the contentSelector element.
  headingSelector: 'h2, h3',

That’s it!

Reference: https://stackoverflow.com/questions/44446671/my-position-sticky-element-isnt-sticky-when-using-flexbox/44446672#44446672