Fixing Focus Visibility Issues with Sticky Navigation in Webflow

Share this post

Rebuild series fixing focus visibility in webflow by Graceful Web Studio

If you’ve ever built a Table of Contents, anchor links, or in-page navigation in Webflow and thought:

“Why is focus technically moving, but users can’t actually see it?”

You’re not alone.

This is one of the most frustrating, subtle, and high-impact accessibility issues in Webflow projects, especially when a site uses a sticky or animated navigation header. It looks like everything is working… until you test it properly with a keyboard or screen reader.

This post breaks down:

  • The exact problem we ran into
  • Why common fixes don’t work in Webflow
  • The Webflow-specific pattern that finally solved it
  • A reusable script you can keep in your toolkit

The Problem: Focus Moves, but Content Is Hidden

Here’s the scenario:

  • A page includes a Table of Contents with anchor links
  • Clicking or activating a TOC link scrolls the page
  • Focus is programmatically moved to the target heading
  • BUT… the heading ends up hidden behind the navigation bar

This is especially common when:

  • The nav is sticky or animated
  • The nav hides on scroll down and reappears on scroll up
  • Webflow Interactions or custom scroll scripts are involved

From a keyboard or screen reader user’s perspective:

  • Focus does move
  • But the focused content is not visible
  • The page feels broken and disorienting

This is a real accessibility failure, not a cosmetic issue.

Why Common Solutions Fail in Webflow

Before finding the fix, we tried all the “standard” approaches you’ll see recommended online.

scroll-margin-top

This only works with native browser anchor scrolling.
If you prevent default behavior and use window.scrollTo() or scrollIntoView(), the browser never applies the margin.

scrollIntoView({ block: "start" })

This doesn’t account for animated headers. The nav often reappears after the scroll completes, covering the focused content again.

❌ Focusing immediately after scrolling

In Webflow, focus can trigger layout reflows. When combined with a nav that animates on scroll direction, this creates a timing race you will lose.

In short:
Webflow’s navigation behavior is a third actor in the system, and most scripts don’t account for it.

The Breakthrough: Focus First, Scroll Last

The key insight was this:

In Webflow, you must allow the navigation to react before you finalize scroll positioning.

The pattern that works is:

  1. Move focus to the target element first
  2. Allow Webflow’s nav and layout to respond
  3. Cancel any in-progress scroll behavior
  4. Correct the scroll position after everything settles

This is not generic JavaScript advice.
This is Webflow-specific reality.

The Reusable Solution Script

Here is the exact pattern we now use for TOCs, anchor links, and any in-page navigation that must work with sticky or animated headers.

The Scroll + Focus Utility Function

<script>
function scrollToElementWithOffset(target, offset = 100) {
  // Ensure the element can receive focus
  target.setAttribute("tabindex", "-1");
  target.focus();

  // Let Webflow/nav animations react first
  setTimeout(() => {
    const rect = target.getBoundingClientRect();
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    const finalPosition = rect.top + scrollTop - offset;

    // Stop any competing scroll behavior
    window.stop();

    // Apply the corrected scroll position
    requestAnimationFrame(() => {
      window.scrollTo({
        top: Math.max(0, finalPosition),
        behavior: "smooth"
      });
    });
  }, 10);
}
</script>

How to Use It (Example: Table of Contents)

tocLink.addEventListener("click", event => {
  event.preventDefault();

  const targetId = tocLink.getAttribute("href").substring(1);
  const target = document.getElementById(targetId);
  if (!target) return;

  scrollToElementWithOffset(target, 100);
});

Why this works in Webflow

  • Focus happens before scrolling
  • The nav finishes animating
  • The final scroll position accounts for the header height
  • Focus remains visible
  • Keyboard, mouse, and screen reader users get the same experience

Accessibility Impact

This pattern directly supports:

  • WCAG 2.4.7 Focus Visible
  • WCAG 2.4.3 Focus Order
  • WCAG 2.1.1 Keyboard

And it prevents one of the most common “it technically works” failures in modern Webflow sites.

When You Should Use This Pattern

Use this approach whenever your Webflow site includes:

  • Sticky or animated navigation
  • Table of Contents components
  • Anchor links
  • “Jump to section” buttons
  • Footnotes or return-to-reference links
  • Any scripted in-page navigation

If focus needs to move and remain visible, this is the pattern to reach for.

Advanced Edge Cases: Sticky Navigation + Inline Footnotes in Webflow

As I continued implementing this pattern across more complex Webflow projects, I ran into additional edge cases that required extending the original solution.

The original focus-first, scroll-last approach still worked conceptually, but certain layouts introduced new challenges that caused anchor targets to remain hidden behind sticky navigation systems.

This became especially noticeable when working with:

  • Multiple stacked sticky navigation menus
  • Animated or auto-hiding headers
  • Inline footnotes and citations
  • Rich text content with small anchor targets
  • Webflow interactions that continue animating after scroll calculations complete

In these situations, standard anchor handling is often not enough. Even after calling preventDefault(), browser hash scrolling, focus behavior, and Webflow interactions can continue competing behind the scenes.

Additional Techniques That Improved Reliability

For more advanced implementations, I found it helpful to:

  • Capture click events earlier using event capture mode
  • Stop competing native scroll behavior more aggressively
  • Move focus first, before calculating scroll position
  • Scroll to the containing paragraph or content block instead of the tiny inline anchor itself
  • Run multiple delayed scroll corrections after layout and navigation animations settle

This last point turned out to be especially important in Webflow.

In some cases, sticky or animated navigation systems continue changing height or visibility after the initial scroll completes. A single correction pass may appear mathematically correct, while still leaving the target visually hidden once the interface finishes animating.

Running additional correction passes after short delays significantly improved reliability across browsers and screen sizes.

Why This Matters

From a keyboard or screen reader user’s perspective, this issue can feel extremely disorienting.

Focus technically moves, but the focused content remains hidden behind navigation. Users lose visual context and may assume the page is broken.

For accessibility, visibility of focused content is just as important as focus movement itself.

Components Most Affected

This issue commonly appears in:

  • Tables of contents
  • In-page navigation systems
  • FAQ jump links
  • Footnotes and citations
  • Documentation systems
  • Glossaries
  • Long-form reports and research pages

As Webflow projects become more interaction-heavy, accounting for these edge cases becomes increasingly important for creating a truly accessible experience.

Final Thoughts

This issue is easy to miss, even for experienced developers. Webflow’s interaction system adds behavior that most generic JavaScript tutorials don’t account for.

Now that we’ve hit this once and documented it, it’s officially part of our Graceful Web Studio accessibility toolkit.

If you’ve ever thought:

“Why does this work everywhere except Webflow?”

This is probably why.

Want to hire me to fix this issue for you. Send me a message on LinkedIn or call me 509-823-6780.

Work With Graceful Web Studio

We build accessible, conversion-focused Webflow websites for businesses across Yakima and the US. Crystal Scott is a Certified Professional in Web Accessibility (CPWA) with 11+ years of front-end experience.

Our services:

Transparent pricing on every service page. Request a quote and get a response within one business day.

Your Website Deserves Better, Let's Team Up

We would love to meet with you face-to-face. Whether virtually or for a coffee. Book a call, and let’s find the right solution for you! We review your site, map goals, and then deliver a clear plan and quote.