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:
- Move focus to the target element first
- Allow Webflow’s nav and layout to respond
- Cancel any in-progress scroll behavior
- 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.
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.
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.

