Dynamic Webflow Table of Contents
This video tutorial provides a comprehensive guide to building a fully dynamic, no-code Table of Contents (TOC) for Webflow projects, specifically designed for long-form blog posts or editorial content. The presented solution eliminates the need for external plugins or writing complex JavaScript from scratch by utilizing a system of custom attributes that automatically scans Rich Text elements to generate navigational links. The instruction ensures that the resulting component works seamlessly with both static and CMS-driven content, prioritizing a clean architecture that requires only a single code embed to function.
The technical implementation focuses on structure and hierarchy, teaching viewers how to configure a "post-content wrapper" that houses both the main text and the sticky navigation sidebar. Key configuration steps include assigning specific attributes such as fc-toc="content" to the source text and fc-toc="component" to the list container, which allows the script to dynamically inject headings ranging from H2 to H6. Furthermore, the video emphasizes high accessibility standards by utilizing semantic HTML tags like <nav> and ordered lists (<ol>) to ensure compatibility with screen readers and assistive technologies.
Beyond basic functionality, the tutorial covers advanced user experience features, including active state highlighting and collapsible heading groups for a cleaner interface. The guide also details a robust mobile strategy where the desktop sidebar transforms into a button-triggered, animated pop-up panel on smaller viewports to preserve screen real estate. By following this workflow, developers achieve a polished, responsive navigation system that enhances content discoverability and maintains context for the reader through automatic scrolling and centering behaviors.
Key Takeaways
- Attribute-Based Configuration: The system relies on specific custom attributes, such as
fc-toc="content"for the source text andfc-toc="component"for the output list, to dynamically generate links without manual coding. - Accessibility First: The build prioritizes semantic structure by using the
<nav>tag and ARIA labels (aria-label="Table of Contents"), ensuring the navigation is interpretable by screen readers. - Dynamic Active States: As users scroll, the script automatically applies an active class (defined by
fc-toc="active-style") to the current link and auto-scrolls the TOC panel to keep the active item centered in view. - Collapsible Hierarchy: By applying
fc-toc-collapse="true", the TOC can nest sub-headings (e.g., H3s under H2s) into expandable groups, reducing visual clutter while allowing users to drill down into specific sections. - Adaptive Mobile Design: To resolve space constraints on smaller devices, the sticky desktop sidebar is replaced by a custom trigger button that opens a modal-style pop-up panel anchored to the bottom of the viewport.
Timestamps
- 2:08 – Assigning the custom attribute
fc-toc="wrapper"to the main container holding both the TOC and the content. - 2:37 – Setting the wrapper grid gap to 5rem and vertical alignment to "top" to ensure proper sticky behavior.
- 3:27 – Applying the attribute
fc-toc="content"to the Rich Text element so the script knows where to source headings. - 4:12 – Setting the TOC element to
position: stickywith a top offset of 150px. - 4:37 – Changing the TOC container’s HTML tag to
<nav>for semantic accessibility. - 5:00 – Adding the attribute
aria-label="Table of Contents"to the navigation element for screen readers. - 5:43 – restricting the list height by setting
max-heightto 50VH andoverflowto "auto" to prevent layout breakage. - 6:24 – Assigning the attribute
fc-toc="component"to the ordered list, designating it as the target for dynamic link injection. - 8:36 – Adding attributes to the template links (e.g.,
fc-toc="h2") to map them to specific heading levels. - 9:21 – Assigning
fc-toc="open-group"to the icon element to function as a collapse/expand toggle. - 9:26 – Setting the
fc-toc="rotate"attribute (e.g., -45) to define the icon's animation during interaction. - 10:13 – Defining the active class for the script to use by applying the attribute
fc-toc="active-style". - 11:40 – Enabling the collapsible hierarchy feature by adding the attribute
fc-toc-collapse="true"to the main list. - 13:09 – Creating a specific container div with the mandatory class name
toc-sub-itemsto wrap collapsible groups. - 13:59 – Setting
overflow: hiddenandmax-height: 0on the sub-items container to create the dropdown effect. - 16:08 – Placing the custom code embed containing the JavaScript inside the post-content wrapper.
- 20:20 – Applying a click interaction to the sticky button (tablet breakpoint) to trigger the mobile pop-up panel.
How to Build a Dynamic, No-Code Table of Contents in Webflow
Phase 1: Structure and Configuration
1. Set Up the Project Wrapper
Timestamp Reference: 02:08 – 02:40
- How: Select the main container element that holds both your future TOC and your blog post content (e.g.,
post-content-wrapper). Apply the custom attributefc-toc="wrapper". Ensure this element is set to a two-column Grid (or Flex) withvertical-align: top. - Why: This attribute defines the scope for the script, identifying the container that holds both the source content and the navigation list. Vertical alignment set to "top" prevents the sticky element from stretching the full height of the container, ensuring sticky scrolling works correctly.
2. Connect the Source Content
Timestamp Reference: 03:27 – 03:40
- How: Select the Rich Text element connected to your CMS post content. Add the attribute
fc-toc="content". - Why: This tells the script exactly which text element to scan. The code will look inside this element to find headings (H2–H6) and generate the links.
3. Position the TOC Container
Timestamp Reference: 04:12 – 04:28
- How: Select the element intended to be the TOC (e.g.,
blog-post-toc). Set its position tostickyand define a top offset (e.g., 150px). - Why: This ensures the TOC follows the user down the page as they read. The offset prevents the TOC from being hidden behind a fixed navbar or sitting too close to the top edge.
4. Configure Accessibility Settings
Timestamp Reference: 04:37 – 05:00
- How: In the element settings panel for the TOC container, change the HTML tag to
<nav>. Add the attributearia-label="Table of Contents". - Why: Using
<nav>identifies the section as a navigation aid to assistive technologies. The ARIA label gives the region a specific name that screen readers can announce to users.
5. Configure the List Component
Timestamp Reference: 05:26 – 06:24
- How: Inside the TOC container, use an Ordered List (
<ol>) element. Add the attributefc-toc="component". In the styles panel, setmax-height(e.g., 50vh) andoverflow: auto. - Why: The Ordered List communicates hierarchy and sequence to screen readers. The
componentattribute designates this list as the target where the script will dynamically inject the generated links. The max-height settings ensure the list becomes scrollable rather than breaking the layout if the post is very long.
Phase 2: Item Template & Styling
6. Create Heading Templates
Timestamp Reference: 06:45 – 08:36
- How: Inside the list, create a list item for each heading level you wish to support (e.g., H2, H3). Inside each item, place a text link. Add the attribute
fc-toc="h2"to the link corresponding to Heading 2,fc-toc="h3"for Heading 3, and so on. - Why: These items serve as templates. The script uses the specific attribute (e.g.,
fc-toc="h2") to map a heading found in the text to the specific visual style you created for that level.
7. Define the Active State
Timestamp Reference: 09:42 – 10:13
- How: Create a specific class (e.g.,
u-doc-current-link) with your desired active styling (e.g., colored text or border). Select your link template and add the attributefc-toc="active-style", pointing to that class. - Why: This attribute tells the script which class to apply when a specific heading scrolls into view. The script automatically toggles this class on and off as the user reads.
Phase 3: Advanced Functionality (Collapsible Groups)
8. Enable Collapse Logic
Timestamp Reference: 11:22 – 11:40
- How: Select the main Ordered List element again. Add the attribute
fc-toc-collapse="true". - Why: This activates the functionality where sub-headings (like H3s) are hidden until their parent group is active, creating a cleaner, compact interface.
9. Add Toggle Icons
Timestamp Reference: 12:06 – 12:54
- How: Inside the H2 list item, add an icon element. Add the attribute
fc-toc="open-group"to the icon. Optionally, addfc-toc="rotate"with a value (e.g., "-45"). - Why: The
open-groupattribute designates the icon as the trigger button to manually expand or collapse a section. Therotateattribute defines the animation angle for the icon when the group is open.
10. Create the Sub-Items Container
Timestamp Reference: 13:09 – 14:10
- How: Create a div block anywhere on the page (e.g., near the rich text) and give it the specific class name
toc-sub-items. Set this class tooverflow: hiddenandmax-height: 0. - Why: This class name is mandatory as it is referenced internally by the script. It acts as the wrapper for nested groups; setting the height to zero ensures they are hidden by default and animate open smoothly.
Phase 4: Implementation and Mobile
11. Implement the Script
Timestamp Reference: 15:59 – 16:15
- How: Add an Embed element containing the provided JavaScript code inside your
post-content-wrapper(or page footer). - Why: This script powers the entire system: scanning content, injecting links, handling scroll spying, and managing animations.
12. Configure Mobile Responsiveness
Timestamp Reference: 19:20 – 20:41
- How: Hide the sticky sidebar on Tablet/Mobile. Create a sticky "Open TOC" button visible only on smaller breakpoints. Apply a click interaction to the button that triggers a pop-up modal containing the TOC list.
- Why: A permanently visible sidebar takes up too much room on mobile screens. Using a button-triggered modal preserves screen real estate while keeping navigation accessible.
FAQs
How to build a dynamic table of contents in Webflow without plugins?
To create a no-code solution, apply the custom attribute fc-toc="content" to your Rich Text element and fc-toc="component" to an empty ordered list block. Use a custom JavaScript embed to automatically scan the text for H2–H6 headings and dynamically inject corresponding anchor links into your list container.
How to make a Webflow table of contents accessible for screen readers?
Set the navigation container's HTML tag to <nav> and add the attribute aria-label="Table of Contents" to clearly define the region for assistive technology. Additionally, use an ordered list (<ol>) structure to communicate the content hierarchy and sequence effectively to users relying on screen readers.
How to create collapsible nested groups in a Webflow table of contents?
Apply the attribute fc-toc-collapse="true" to your main list and use a toggle icon with the attribute fc-toc="open-group" to control visibility. Wrap the collapsible sub-items in a div with the specific class toc-sub-items, setting its overflow to hidden and max-height to zero to create a dropdown effect.
How to highlight active links in a Webflow table of contents while scrolling?
Create a specific CSS class that defines your active state (e.g., a colored border) and assign it to the link element using the attribute fc-toc="active-style". A script will then track the viewport and automatically apply this class to the navigation link corresponding to the heading currently visible on the screen.