To make an element sticky in Webflow, select it, go to Style Panel (S) → Position → Sticky, then set Top: 0 (or any offset). Sticky elements scroll with the page until they hit their offset, then stick in place. Set Z-index: 999 to keep the sticky element above other content. For a fixed CTA button that never scrolls, use Position: Fixed instead of Sticky — Fixed elements are always in the same viewport position regardless of scroll.
Webflow Sticky Elements: Position Sticky, Fixed CTAs, and Hide-on-Scroll Navbar
Sticky positioning is one of the most requested layout techniques in Webflow — used for navbars that stay visible while scrolling, sidebars that lock alongside long content, and floating CTA buttons that are always accessible. The key distinction in Webflow is between Position: Sticky (stays within its parent's boundary, natural document flow) and Position: Fixed (always in the same viewport position, outside document flow). This tutorial covers both, along with the hide-on-scroll navbar pattern (navbar that hides when scrolling down and reappears when scrolling up), sticky sidebars for long-form content pages, and the offset fix for anchor links when a sticky navbar is present. This is specifically about positioning technique — not about the Navbar component's structure, which is covered in the Navbar tutorial.
Prerequisites
- A Webflow project open in the Designer with at least one long-scrolling page
- Basic understanding of the Style Panel (S) Position section and Z-index
- For the hide-on-scroll pattern: familiarity with the Interactions panel (H) and Page triggers
Step-by-step guide
Make a Navbar sticky with Position: Sticky
Make a Navbar sticky with Position: Sticky
Select the Navbar element (or any element you want to make sticky). Go to Style Panel (S) → Position section → click the Position dropdown and select Sticky. Immediately below, set Top: 0px. This tells the browser: 'scroll normally until you reach 0px from the top of the viewport, then stick there.' A Z-index must be set for sticky elements to render above content they overlap — Style Panel → Position → Z-index: 999. Important: Position: Sticky only works within the element's parent container boundaries. If the parent container ends, the sticky element stops sticking and scrolls away with the parent. This is intentional for sidebars (sticks until the content section ends) but can surprise navbar builders who nest the navbar inside a Section.
Expected result: The navbar element sticks to the top of the viewport when the page is scrolled. In the Designer, add a long section below and use Preview (eye icon) to test the sticky behavior.
Use Position: Fixed for a floating CTA button
Use Position: Fixed for a floating CTA button
Position: Fixed removes the element from the document flow entirely and anchors it to the viewport — it stays in the same position even when the page scrolls. This is ideal for a floating 'Book a Call' button or a 'Back to Top' button. Select your CTA Div Block or Button element → Style Panel → Position → Fixed. Set the corner position: Bottom: 24px, Right: 24px. Set Z-index: 1000. Add a high border radius (Style Panel → Borders → Border Radius: 50px) for a pill shape. For a shadow that elevates the button: Style Panel → Effects → Box Shadows → '+' → X: 0, Y: 4px, Blur: 20px, Color: rgba(0,0,0,0.2). The element is now completely removed from the page flow — other content flows as if the fixed element does not exist.
Expected result: The CTA button floats in the bottom-right corner of the viewport at all scroll positions. It does not move or shift when scrolling.
Build a hide-on-scroll navbar using Interactions
Build a hide-on-scroll navbar using Interactions
A navbar that hides when scrolling down (to give content more space) and reappears when scrolling up (for easy navigation access) requires Webflow Interactions. The navbar must be Position: Fixed or Sticky with Top: 0. Open the Interactions panel (H) → Page triggers → '+'. Select trigger type 'When scrolled down past' — set a threshold (e.g., 150px). 1st action: target the Navbar element, Move Y to -100% (or -80px, enough to hide it), Duration 300ms, Ease In. Select 'When scrolled up past' with the same threshold. Action: Move Y back to 0px, Duration 300ms, Ease Out. This creates the hide-on-scroll behavior without removing the navbar from the layout.
Expected result: In preview mode, scrolling down hides the navbar with a smooth upward slide. Scrolling up brings it back with a smooth downward slide.
Create a sticky sidebar in a two-column layout
Create a sticky sidebar in a two-column layout
A sticky sidebar that locks alongside long main content is common for documentation, blog posts, and product pages. Build a two-column layout: parent Div (Style Panel → Layout → Display: Flex → Direction: Horizontal → Align: Flex Start). Inside, create two child divs: 'main-content' (Style Panel → Layout → Flex Child → Custom → Grow: 1) and 'sidebar' (Style Panel → Size → Width: 280px, Flex Child → Shrink). On the 'sidebar' div: Style Panel → Position → Sticky → Top: 24px. The sidebar will scroll with the page until it reaches 24px from the viewport top, then stick there while the main content continues scrolling below. The sidebar returns to normal when the parent container ends.
Expected result: In preview mode, the sidebar sticks 24px from the top while the main content scrolls past it. When the parent section ends, the sidebar scrolls away naturally.
Fix anchor link offset for sticky navbar
Fix anchor link offset for sticky navbar
When a sticky navbar is present, clicking an anchor link (#section-id) scrolls the page so the target section's top edge aligns with the viewport top — which puts it directly behind the sticky navbar. The fix is a scroll margin or scroll padding. For each section that is an anchor target, select it → Style Panel → Custom Properties (bottom of Style Panel) → '+' → Property: scroll-margin-top, Value: 80px (the height of your navbar). This pushes the scroll target down by 80px, so it appears below the sticky navbar when jumped to. Alternatively, add a CSS rule in Project Settings Head Code to apply this globally.
1/* Add to Project Settings → Custom Code → Head Code */2/* Adjust 80px to match your actual sticky navbar height */3<style>4 [id] {5 scroll-margin-top: 80px;6 }7</style>Expected result: Clicking anchor links in the nav scrolls the page so the target section appears below the sticky navbar with correct spacing, not hidden behind it.
Add a transparent-to-solid background on scroll to a sticky navbar
Add a transparent-to-solid background on scroll to a sticky navbar
A common pattern for hero-heavy landing pages: the navbar starts transparent over the hero image and transitions to a solid background after the user scrolls past the hero. With the Navbar set to Position: Sticky, Top: 0, open the Interactions panel (H) → Page triggers → '+' → 'While page is scrolling' (continuous scroll mapping). In the animation: at 0% scroll position, set Navbar Background Color to transparent (rgba(0,0,0,0)). At 10% scroll position, set Background Color to your solid brand color (e.g., white #FFFFFF). This creates a smooth transition as the user scrolls through the hero section.
Expected result: In preview mode, the navbar starts transparent over the hero, then smoothly fades to a solid background color as the user scrolls. A box shadow appears at the same time.
Verify sticky behavior across all breakpoints
Verify sticky behavior across all breakpoints
Sticky and Fixed positioning behavior differs significantly on mobile browsers. iOS Safari has historically had quirks with position:sticky inside overflow:hidden containers — if the sticky element is not working on iPhone, check whether any parent container has overflow:hidden or overflow:auto set, as this breaks sticky behavior. Switch through all breakpoints in the Breakpoint Bar. On Mobile Portrait, check that the sticky navbar has enough padding for the mobile layout and that Fixed CTAs are not blocking tap targets in the main content. Also check that the hide-on-scroll Interaction is disabled on Mobile if it causes performance issues (Interactions panel → uncheck the Mobile Portrait breakpoint checkbox in the trigger settings).
Expected result: Sticky behavior works correctly at Desktop, Tablet, and Mobile. On iOS Safari, the navbar sticks without glitching. Fixed CTA buttons do not block content on mobile.
Complete working example
1<!-- STICKY NAVBAR ANCHOR LINK OFFSET FIX -->2<!-- Add to Project Settings → Custom Code → Head Code -->3<!-- Adjust 80px to match your actual navbar height -->4<style>5 /* Apply scroll-margin-top to all elements with an ID (anchor targets) */6 [id] {7 scroll-margin-top: 80px;8 }910 /* More specific selector if you want to target only sections -->11 section[id],12 div[id] {13 scroll-margin-top: 80px;14 }15</style>1617<!-- OPTIONAL: Smooth scroll behavior site-wide -->18<!-- Webflow handles anchor link smooth scroll automatically for built-in nav links -->19<!-- For custom JS-triggered scrolling, use this: -->20<style>21 html {22 scroll-behavior: smooth;23 }24</style>2526<!-- OPTIONAL: Override smooth scroll for users with reduced motion preference -->27<style>28 @media (prefers-reduced-motion: reduce) {29 html {30 scroll-behavior: auto;31 }32 }33</style>Common mistakes
Why it's a problem: Position: Sticky is not working — the element scrolls away normally
How to avoid: The most common causes: 1) A parent container has overflow:hidden set (Style Panel → Size → Overflow → Hidden) — this breaks sticky in all browsers. Remove it or restructure the layout. 2) The parent container is not tall enough — sticky only works while inside the parent boundaries. 3) The Top offset is not set — Sticky without Top/Left/Right/Bottom specified has no effect.
Why it's a problem: Fixed CTA button position shifts unexpectedly on certain pages
How to avoid: Position: Fixed is anchored to the viewport, but CSS transforms, filters, or perspective on any ancestor element create a new stacking context that overrides Fixed positioning and makes it behave like Absolute. Check all parent elements of the fixed CTA for transform, filter, or perspective styles in Style Panel → Effects → 2D & 3D Transforms and Filters.
Why it's a problem: Anchor links jump to sections but the target is hidden behind the sticky navbar
How to avoid: Add scroll-margin-top to the target sections via Style Panel → Custom Properties → scroll-margin-top: 80px (use your navbar's actual height). Or add the CSS snippet from the complete code above to Project Settings Head Code to apply it globally to all anchor targets.
Why it's a problem: Hide-on-scroll interaction fires on page load, hiding the navbar immediately
How to avoid: The While Scrolled Down trigger needs a minimum scroll threshold to prevent triggering on page load. Set the scroll threshold to at least 150px in the trigger settings. Also check that the Interaction's 'Set Initial Appearance' is not incorrectly applying the hidden state — verify the Initial Appearance shows Move Y: 0.
Best practices
- Use Position: Sticky (not Fixed) for navbars and sidebars when you want the element to stop sticking when its parent section ends — this is more layout-aware and avoids z-index complications.
- Always set a Z-index on sticky and fixed elements (999 for navbar, 1000 for modal overlays, 100 for sidebars) — without Z-index, sticky elements can be hidden behind other elements.
- Add scroll-margin-top to all anchor target sections equal to the sticky navbar height — missing this fix is the #1 cause of anchor links appearing to scroll to the wrong position.
- Test sticky behavior on real iOS Safari — overflow:hidden on any parent container breaks position:sticky in Safari, and this is a very common layout mistake.
- For hide-on-scroll navbars, use the Page trigger 'When scrolled down' rather than 'While page is scrolling' — the discrete trigger fires once (less CPU usage) instead of firing on every scroll frame.
- Keep fixed CTAs below 60×60px touch target size and positioned in a corner (bottom-right is standard) — larger or centered fixed elements block reading and frustrate mobile users.
- Add CSS transitions to sticky elements in their None state so scroll-triggered Interaction animations appear smooth even between rapid scroll direction changes.
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a Webflow landing page with a sticky navbar that starts transparent over the hero section and becomes solid white after the user scrolls 100px. I also want it to hide when scrolling down and show when scrolling up. Explain the Webflow Position settings, Interactions panel triggers I need, and any Z-index considerations. Reference the specific Webflow panel names and trigger types.
My Webflow navbar is set to Position: Sticky, Top: 0, Z-index: 999, but it is not sticking on mobile Safari. The navbar is inside a Section element that has Overflow: Hidden set. Is this the cause of the issue? What is the correct structure for a sticky navbar in Webflow so it works on all browsers including iOS Safari?
Frequently asked questions
What is the difference between Position Sticky and Fixed in Webflow?
Position: Sticky (Style Panel → Position → Sticky) scrolls with the page normally until it reaches its Top offset, then sticks. It stays within its parent container boundaries and returns to flow when the parent ends. Position: Fixed (Style Panel → Position → Fixed) removes the element from document flow entirely — it is always at the same viewport position regardless of scroll, and its parent container has no effect on it.
Why does position:sticky stop working in Safari on iOS?
The most common cause is a parent element with overflow:hidden or overflow:auto set. In Safari (and all browsers), overflow:hidden on a parent breaks position:sticky for children, as the overflow creates a new scrolling context. Open the Navigator (Z) and check every ancestor element of the sticky element for Overflow: Hidden in their Size settings. Remove the overflow:hidden or restructure the layout to avoid it.
How do I make a sticky element stop sticking after a certain section?
Position: Sticky naturally stops sticking when its parent container ends — the sticky element scrolls away with the parent. To control the sticky range precisely, place the sticky element inside a wrapper Div that spans exactly the section where you want sticking to occur. When the wrapper div scrolls out of view, the sticky element will scroll with it.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation