You’ve seen it on the Apple product pages. You’ve seen it on Awwwards. You scroll down, but the section doesn’t leave. Instead, the phone spins, the text fades in, or the next card slides over the top.
This is called Pinning.
It is the single most powerful technique in modern web storytelling. It transforms a website from a document into a movie. But if you try to achieve this with basic CSS position: sticky, you will hit a wall. To get that cinematic feel, you need ScrollTrigger Pinning.
In this guide, I will teach you how to create full page scrolling animations with GSAP, dissect the code behind the “Stacking Cards” and “Horizontal Scroll” effects, and show you how to turn these complex layouts into reusable assets with Kitstarter.io.
What is "Pinning" in GSAP? (Beyond CSS Sticky)
In standard web browsing, when you scroll down 100 pixels, the content moves up 100 pixels. It is a 1:1 relationship.
Pinning breaks this relationship.
When you set pin: true in GSAP’s ScrollTrigger, you are telling the browser: “Let the user keep scrolling their mouse wheel, but freeze this specific element in the viewport.”
This creates a disconnect between Time (scroll progress) and Space (visual movement). While the element is pinned, you can use that “scroll time” to animate other things—rotating a 3D model, filling a progress bar, or fading in text.
Technique 1: The "Layered-Pin" (Stacking Cards Effect)
This is the trend of 2025/2026. Imagine a series of colored sections that stack on top of each other like a deck of cards, rather than scrolling past.
The Logic
We don’t need complex math here. We simply need to tell every “panel” to pin itself when it hits the top of the screen.
// Register the plugin
gsap.registerPlugin(ScrollTrigger);
// Select all panels
const panels = gsap.utils.toArray(".panel");
panels.forEach((panel, i) => {
ScrollTrigger.create({
trigger: panel,
start: "top top", // When top of panel hits top of viewport
pin: true, // Freeze it!
pinSpacing: false, // Vital: This allows the next panel to slide UNDER or OVER it
end: "max" // Pin until the very end of the container
});
});
Expert Note: The secret ingredient here is pinSpacing: false. By default, GSAP adds padding to push content down so it doesn’t overlap. By turning this off, we intentionally create that “stacking” overlap effect.
Technique 2: The Horizontal Scroll (Side-Scrolling Gallery)
Clients love asking for this: “I want to scroll down, but have the images move sideways.”
To do this, we combine Pinning with a Transform. We pin the entire section so it stays in the viewport, and while it is pinned, we translate the content to the left.
const gallery = document.querySelector(".horizontal-gallery");
const wrapper = document.querySelector(".gallery-wrapper");
gsap.to(gallery, {
xPercent: -100, // Move the gallery all the way to the left
x: () => window.innerWidth, // Offset so the last item is visible
ease: "none", // Linear movement is crucial for scrolling
scrollTrigger: {
trigger: wrapper,
start: "top top",
end: () => "+=" + wrapper.offsetWidth, // The scroll distance = width of gallery
pin: true,
scrub: 1, // Smooth scrubbing
invalidateOnRefresh: true // Recalculate on resize
}
});
Workflow Revolution: Packaging Pinning Logic with Kitstarter.io
Here is the brutal truth about being a creative developer: Pinning logic is fragile.
You spend 4 hours tweaking the end values, fixing the mobile responsiveness, and ensuring the pinSpacing doesn’t break the footer. You deliver the site. The client loves it.
Two weeks later, a new client wants a “Horizontal Scroll Section.”
Do you write the code again from scratch? Do you hunt through your old GitHub repos, copy-paste the JS, and pray the HTML structure matches?
No. You use Kitstarter.io.
Kitstarter allows you to productize your code.
Build your perfect “Horizontal Scroll” section in Elementor (using the GSAP code above).
Package it with Kitstarter. This saves the HTML structure, the CSS, and the GSAP Javascript into a single JSON kit.
Deploy it on any future site in one click.
With Kitstarter, you aren’t just coding; you are building a Library of Mechanics. You can even monetize this. I know developers making passive income selling “GSAP Scrollytelling Kits” via Kitstarter to other designers who don’t know how to write the code I just showed you.
Comparison: CSS "position: sticky" vs. GSAP "pin: true"
Why not just use CSS? It’s native, right? Here is why GSAP is the professional choice.
| Feature | CSS position: sticky | GSAP ScrollTrigger Pin |
| Setup | Easy (1 line of CSS) | Moderate (JS setup) |
| Duration Control | ❌ None (Unsticks when parent ends) | ✅ Precise (Set end to any pixel value) |
| Animation Sync | ❌ Hard (Requires IntersectionObserver) | ✅ Native (Sync timelines to pin duration) |
| Cross-Browser | ⚠️ Flaky on some wrappers | ✅ Consistent everywhere |
| Complex Stacking | ❌ Difficult to layer | ✅ Easy (pinSpacing control) |
FAQ: Fixing Common Pinning Bugs
Q1: Why is there huge white space below my pinned section?
A: This is pinSpacing. By default, GSAP adds padding to your container equal to the duration of the scroll, so the content below doesn’t shoot up. If you are doing a “Stacking” effect, set pinSpacing: false. If you are doing a normal sequence, you need that white space—you just need to fill it with your animation.
Q2: My pinned element shakes/jitters on mobile.
A: Mobile browsers hide/show the address bar as you scroll, which resizes the viewport and forces GSAP to recalculate. To fix this, use ScrollTrigger.normalizeScroll(true) or ignore the address bar resize in your config.
Q3: Can I pin something inside an Elementor container?
A: Yes, but be careful. Elementor often adds overflow: hidden to sections. Sticky/Fixed elements cannot work inside an overflow: hidden parent. You might need to use CSS to set overflow: visible on the Elementor section wrapper.
Conclusion
Mastering ScrollTrigger Pinning is what separates the “Template Users” from the “Experience Creators.” It gives you control over Time and Space on the browser.
By understanding how to create full page scrolling animations with GSAP, you can guide your user’s attention with surgical precision. And when you combine this technical skill with Kitstarter.io, you stop trading time for money. You build the logic once, package it, and profit from it forever.
Ready to freeze time? Open your editor, set pin: true, and start controlling the narrative.


