Gatsby: Floating Table of Contents for longer docs (ToC)

Created on 31 Jul 2018  Â·  19Comments  Â·  Source: gatsbyjs/gatsby

@calcsam idea: Quip writing app does this in a clean and clear way

screen shot 2018-07-31 at 10 09 07 am

documentation

Most helpful comment

Small update: The above mentioned ToC implementation no longer relies on #13972 and now highlights the currently active section of the document. Also wrote a short blog post about it.

toc

All 19 comments

Hi @fk I put this in the Docs redesign phase 3 EPIC, open to discussion on how to prioritize it!

👍

@shannonbux you might be interested in checking out this Gatsby starter I've been working on which implements a floating TOC like you've described. I can't remember exactly why it wasn't sufficient for my use case, but my implementation does not make use @DSchau's TOC plugin

Hi @johncmunson, cool starter! I don't see the floating TOC yet - am I missing something?

Also, just realizing this issue could be split into two

  1. Implement TOC in gatsbyjs.org
  2. Write a doc that explains how to implement TOC on any site

Finally, have you submitted your starter to the starter library yet?

@shannonbux it only displays on larger screen widths. You may need to drag the browser wider than the full width of your screen. My implementation utilizes @researchgate/react-intersection-observer and react-scroll, but I think a more generic TOC could have foregone the use of react-scroll.

To get the IntersectionObserver api to work on mobile (b/c even though the TOC doesn't display on mobile, I'm still updating the URL hash as the user scrolls), I needed to yarn add intersection-observer and add this snippet to gatsby-browser.js...

const getPolyfills = () => {
  if (!('IntersectionObserver' in window)) {
    require('intersection-observer')
  }
}

exports.onClientEntry = () => {
  getPolyfills()
}

I haven't yet added to the starter library, will be sure to do that when my starter is feature complete.

@johncmunson that would be excellent. @fk Do you think there would be enough whitespace in docs to implement something like this? This isn't necessarily a top priority, unless @johncmunson you want to work on it!

@shannonbux Yep, I think starting from at around 1300px viewport width we should have enough whitespace.

Sounds pretty fun, I'll take a look this week and see what I come up with!

sounds great!

On Mon, Dec 17, 2018 at 7:49 AM John Munson notifications@github.com
wrote:

Sounds pretty fun, I'll take a look this week and see what I come up with!

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/gatsbyjs/gatsby/issues/6896#issuecomment-447892337,
or mute the thread
https://github.com/notifications/unsubscribe-auth/Ae9o2tunWHEIEvFYuOw8CyNxJYmIs7hqks5u57z4gaJpZM4VoqGN
.

Not stale!

@shannonbux, @marcysutton and I brainstormed on this today and we came up with some ideas on how we could implement this.

On large displays, we have room on the right side of the page to have a sticky section on the right side of the screen that we could have to notify people of their current place in the current document and it would stay in place as we scroll down the document. Below I show how we will take the table of contents out of the normal flow of the document and into a sidebar-like area:

Large Display TOC

As well, on mobile, we could keep the TOC in the flow of the document but move it up to right under the main heading of the page:

Mobile TOC

@fk we'd appreciate some feedback if this feels alright or if there may be a better way to display a table of contents on each form-factor.

if this feels alright

đź’Ż, it does!

IMO for the first shot we don't even need to worry too much about making the ToC sticky when it's displayed as a "sidebar", although it'd be nice to have! FWIW here's something similar I did recently:

image

image

We now have presets.letterSpacings to help with styling the small caps ToC headline.

I just coded up a floating ToC very similar to what is being discussed here. You can check it out in action here. Here's the code. It relies on #13972.

floating-toc

Some more information and success criteria from our specification doc:

A floating table of contents widget will help users contextualize where they are in a document, dynamically listing page sections and scrolling with them as they read.

The floating TOC should include a heading like “Table of Contents” to be consistent with the Gatsby Preview docs. It should also include a list of internal links to each of the h2, h3, and possibly h4 headings in the document (need to play around with this–it might be nice to make it configurable). All text colors should be evaluated to meet color contrast requirements (4.5:1 for smaller, non-bold text).

The widget could potentially leverage Remark plugins. It should live in the DOM source between the h1 heading and the article’s main body to allow it to float in the right column at large viewports and slide under the h1 heading on smaller viewports.

Acceptance Criteria

  • As a user, I should be able to orient myself in a doc with a heading declaring a “Table of Contents” and a list of internal links to h2 and h3 headings
  • As a sighted or moderately low-vision user, I should encounter adequate color contrast for headings and links
  • As a screen reader user, I should recognize the table of contents as a <nav> element with a unique label. Inside I should find a heading and a list of contents.

    • Two techniques are to use aria-labelledby to point to the first heading’s ID or an aria-label directly on the element

  • As a sighted user with a large viewport, I should see the table of contents follow my scroll position as I navigate through the page.
  • As a sighted user with a smaller viewport, I should see the table of contents following the h1 heading.

Small update: The above mentioned ToC implementation no longer relies on #13972 and now highlights the currently active section of the document. Also wrote a short blog post about it.

toc

So I'm going to take a dive into implementing this issue this weekend. If I can get a PR up, I'll likely be contacting @fk for some design advice so it fits into the current site design and @marcysutton to make sure it's accessible.

I will as well look into the implementations that @janosh did on his personal blog.

@lannonbr reactjs.org does something like below gif on mobile devices.
ScreenRecording2019-07-03at1

@gagan0723 So we actually already have that functionality for the sidebar on mobile layouts in the various layouts to go between different pages. This issue is specifically for making a Table of Contents for different sections of a single page.

@lannonbr Significant parts of the reactjs.org implementation could probably still be reused for in-page navigation.

Was this page helpful?
0 / 5 - 0 ratings