Updated on August 06, 2018

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.

Live Demo

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

Need help implementing a tutorial in your site or want to hire me for custom work?


Find the article helpful and wish to donate?



For adding code blocks wrap the code in three backticks. Markdown should work.
Provide a URL of your site/webpage if something is not working.

8 comments on “Automatic Table of Contents using Tocbot in Oxygen”

  1. Why is this so complicated? I would like to use just a shortcode to add the TOC. It’s a pain in the ass that other TOC-plugins don’t work with Oxygen.

      1. I tried “CM Table of Contents” and “Easy Table of Contents”. The shortcode of the first didn’t render, and the latter should include the TOC automatically, but nothing happened.

  2. Hi Sridhar, awesome! it worked like a charm

    I implemented a bit of a workaround to avoid my sticky header to cover my targeted headings, like this:

    @media (min-width:993px)
    :target::before {
    display: block;
    content: ” “;
    height: 100px;
    margin-top: -100px;
    visibility: hidden;

    The problem is whenever I click an item in the TOC, the corresponding heading gets an ugly border until I click somewhere else (including the :before pseudoclass height).

    How can I get rid of that border on the heading?

    Thank you!

  3. Got it! I was doing it the wrong way

    Ended up with this:

    @media (min-width:993px)
    h1::before, h2::before, h3::before, h4::before, h5::before, h6::before
    display: block;
    content: ” “;
    height: 85px;
    margin-top: -85px;
    visibility: hidden;
    outline: none;

    h1::focus,h2::focus,h3::focus,h4::focus,h5::focus,h6::focus, h1::active,h2::active,h3::active,h4::active,h5::active,h6::active

    1. // Headings offset between the headings and the top of the document (this is meant for minor adjustments).
      headingsOffset: 1,

      this helped me …

linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram
%d bloggers like this: