Scrolltrigger , Elementor, GSAP

Create Horizontal Scroll Animation with staggered Text and parallax Image

SHARE

Horizontal scroll Elementor GSAP with staggered text

Elementor Pro Users

1. Setup of your Page in Elementor

Use this setup and the code if you don’t plan to have additional movement Scroll Triggers inside the Horizontal Scroll. 

Copy this code in the Custom CSS

  • Create a Scrollcontainer
    •  Flexbox, Full Width, Width 100%,
    • Min Height 100vh
    • Overflow: Hidden 
    • Margin 0, Padding 0
    • CSS Classes: scroll-container
    • Custom CSS for Elementor Pro –> Put this in your custom code or in the Advanced Tab in the Custom CSS
.scroll-container{
    transition: none;
    overscroll-behavior: none;
    
   /* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/
    
    display:flex !important; 
    width:100% !important;
    Height: 100vh !important;
    overflow: hidden !important; 
    margin: 0px !important; 
    padding: 0px !important;
}
  • Create a Scroll Content Container
    •  Flexbox, Full Width,
    • Width auto ,
    • Min Height 100vh
    • Wrap: No Wrap, Gaps: 0, direction: Row Horizontal
    • Margin 0, Padding 0
    • CSS Classes: scroll-content
    • Custom CSS for Elementor Pro –> Put this in your custom code or in the Advanced Tab in the Custom CSS
.scroll-content{
    transition: none;
    overscroll-behavior: none;
    
     /* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/
     
    display:flex !important; 
    width: 400vw !important; 
    height: 100vh !important; 
  flex-wrap: nowrap !important; 
  gap: 0 !important; 
  flex-direction: row !important; 
  margin: 0 !important; 
  padding: 0 !important; 
}

Panel Container CSS

Container Setup

  • Desktop
    •  Flexbox, Full Width,
    • Width 100vw,
    • Min Height 100vh
    • Direction: Row horizontal, 
    • Justify Content: Space Between 
    • Gaps: 5vw, 5vw
    • HTML Tag: section (important because otherwise GSAP code is not working)
    • Align Items: Center
    • Style: Image Background, Center Center, Cover 
    • Background Overlay:
      • Black,
      • 0,6 Opacity
    • Margin 0, Padding 10vw
    • Size: Custom, Flex Grow 1, Flex Shrink 0. (important for horizontal scroll to work) 
    • CSS Classes: panel
  • Tablet and Mobile  (only values which will change) 
    • Direction: Column vertical 
    • Justify Content: Center
    •  Gaps: 2vw, 2vw
 /* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/

.panel {
  display: flex !important; 
  width: 100vw !important; 
  height: 100vh !important; 
  flex-grow: 1 !important; 
  flex-shrink: 0 !important; 
  flex-basis: auto; 
  box-sizing: border-box !important; 
}

Content Setup

Heading Container Panel 1

  • Desktop
    •  Flexbox, Full Width, 
    • Width 70%
    • Direction: Columns vertical,  
  • Tablet and mobile (only values which will change) 
    • Width: 100%

Heading Setup

  • Desktop
    • Text: Transform Your Online Presence with Stunning Web Design!, h2
    • Style: Color: White
    • Font: Family: Playfair Display, 5rem, weight: 600
    • Margin Bottom: 24px
  • Tablet and Mobile
    • Font-Size Tablet : 3.5rem
    • Font-Size Mobile: 2.5rem
    • Class Name: text

Text Setup

  • Text Setup Desktop
    • Text: Scroll down to explore how we create impactful websites that not only look amazing but also perform exceptionally. Let’s start your journey to online success!
    • Text Style: Color White, Font Family Roboto, Font-Size: 1.6rem
    • CSS Class: text
  • Text Setup Tablet and Mobile
    • Font-Size Tablet: 1.4rem
    • Font-Size Mobile: 1.2rem

Rotating Text Container

  • Desktop:
    • Flexbox, Full Width, Width 30%
    • Min Height: 17vw
  • Tablet and Mobile:
    • Width: 100%
    • Min Height Tablet : 25vw
    • Min Height Mobile: 35vw
  • Setup Rotating Text Circle (see my Video for it for details)
    • Change Horizontal Orientation to End
    • Icon Settings:
      • Size Desktop: 5vw 
      • Size Tablet: 7vw
      • Size Mobile: 8vw
      • Class: Icon
 

Panel 2, 3 and 4 Container and Content

Panel Setup

  • Panel Setup Desktop
    •  Flexbox, Full Width,
    • Width 100vw,
    • Min Height 100vh
    • Direction: Row horizontal,
    • Gaps: 0vw, 5vw
    • HTML Tag: section (important because otherwise GSAP code is not working)
    • Style: Background Color: black
    • Margin left: -1,
    • Padding 10vw
    • Size: Custom, Flex Grow 1, Flex Shrink 0. (important for horizontal scroll to work) 
    • CSS Classes: panel
  • Panel Setup Tablet and Mobile  (only values which will change) 
    • Direction: Column vertical
    • Justify Content: Center
    •  Gaps: 5vw, 5vw

Text Container

  • Container Setup for Texts Desktop
    • Flexbox, Full width, Width 60%
    • Justify Content: Center
    • Direction: Column Vertical
    • Align Items: Left
    • Gaps: 0
    • Margin: 0
    • Padding: 0
    • CSS Class: container
  • Container Setup Tablet and Mobile
    • Width: 100%

Hiding Container for Texts

  • Number Container
    • Flexbox, Full width, Width 100%
    • Overflow Hidden (for stagger effect)
    • Padding Bottom: 10px

Copy This container twice for efficiency 🙂

  • Container Staggered Heading
    • Margin Desktop Bottom: 20
    • Padding Desktop Bottom: 20
    • Margin Tablet Bottom: 16
    • Padding Tablet Bottom: 16
    • Margin Mobile Bottom: 12
    • Padding Mobile Bottom: 12
  • Text Editor Widget Container:
    • nothing to add
  •  

Text Setup

  • Heading Number Setup
    • Content: 01
    • Text Color: White
    • Font-Family: Playfair Display
    • Font-Size Desktop: 3rem
    • Font-Size Tablet: 2.4rem
    • Font-Size Mobile: 1.6rem
    • CSS Class: text
  • Staggered Text:
    • Content: Custom<br> Webdesign
    • Text-Color: White
    • Font-Family: Playfair Display
    • Font-Size Desktop: 6rem
    • Font-Size Tablet: 4.5rem
    • Font-Size Mobile: 2.5
    • CSS Class: text 
  • Texteditor Setting:
    • Content:
      • We craft stunning websites that reflect your unique brand identity. Whether you need a fresh redesign or a brand-new site, we’ve got you covered. 
    • Font Family: Roboto
    • Fontsize Desktop: 1.6
    • Fontsize Tablet: 1.4
    • Fontsize Mobile: 1.1
    • CSS Class: text-two

Image Container

    • Container Desktop 
      • Flexbox, Full Width, Width 40%
      • Justify Content: Bottom
    • Container Tablet and Mobile
      • Width: 100%
    • Image Desktop
      • Add an Image
      • Style: Width: 100% (can also be less)
      • CSS Class: img
    • Image Tablet and Mobile
      • Tablet Width: 50%
      • Alignement: Left
      • Mobile Width: 60% 

    Copy this Panel two times. 

    Add HTML Widget and Paste the Code in from below.

  •  

Copy the just Created Panel two times and fill in your individual content for each panel

GSAP Code for your HTML Widget

<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/split-type@0.3.4/umd/index.min.js"></script>


 <script>
  document.addEventListener("DOMContentLoaded", () => {
    gsap.registerPlugin(ScrollTrigger);

    let container = document.querySelector(".scroll-content");
    let scrollContainer = document.querySelector(".scroll-container");

    if (!container || !scrollContainer) {
      console.error("Container oder Scroll-Container nicht gefunden. Überprüfe die Klassennamen.");
      return;
    }

    // Timeline for horizontal scrolling and parallax effects
    let scrollTimeline = gsap.timeline({
      scrollTrigger: {
        trigger: scrollContainer,
        pin: true,
        scrub: 1,
        start: "top top",
        end: () => "+=" + container.scrollWidth,
        markers: false,
        invalidateOnRefresh: true,
      },
    });

    // Add Horizontal Scroll to Timeline
    scrollTimeline.to(container, {
      x: () => -(container.scrollWidth - window.innerWidth),
      ease: "none",
    });

    // Zerlege den Text in Buchstaben
    document.querySelectorAll(".panel .text").forEach((textElement) => {
      new SplitType(textElement, { types: "chars" });
    });

    // Animieren der Buchstaben in jedem Panel
    document.querySelectorAll(".panel").forEach((panel) => {
      const chars = panel.querySelectorAll(".char"); // Buchstaben des Panels auswählen

      if (chars.length > 0) {
        gsap.from(chars, {
          y: 200,
          opacity: 1,
          duration: 2,
          ease: "power1.out",
          stagger: 0.05, // Verzögerung zwischen Buchstaben
          scrollTrigger: {
            containerAnimation: scrollTimeline, // Verknüpfe mit horizontalem Scroll
            trigger: panel,
            start: "left 60%",
            end: "left 30%",
            scrub: true,
            markers: false,
        
          },
        });
      }
    });

    // Animieren der Bilder in jedem Panel
    const panels = gsap.utils.toArray(".panel");
    panels.forEach((section, index) => {
      const images = section.querySelectorAll(".img");

      if (images.length > 0) {
        images.forEach((image) => {
          if (index === panels.length - 1) {
            gsap.from(image, {
              x: "+0",
              opacity: 0.5,
              scale: 0.5,
              ease: "power2.out",
              scrollTrigger: {
                containerAnimation: scrollTimeline,
                trigger: image,
                start: "left 100%",
                end: "left 50%",
                scrub: true,
                invalidateOnRefresh: true,
                markers: false /*{
                  startColor: "green",
                  endColor: "orange",
                  fontSize: "14px",
                  indent: 20,
                },*/
              },
            });
          } else {
            gsap.from(image, {
              x: +200,
              opacity: 0.5,
              scale: 0.5,
              scrollTrigger: {
                containerAnimation: scrollTimeline,
                trigger: image,
                start: "left 100%",
                end: "left 0%",
                scrub: 1,
                invalidateOnRefresh: true,
                markers: false /*{
                  startColor: "blue",
                  endColor: "red",
                  fontSize: "12px",
                  indent: 20,
                },*/
              },
            });
          }
        });
      } else {
        console.warn("Keine Bilder gefunden in:", section);
      }
    });

    // Animation für alle Elemente mit der Klasse "text-two"
    document.querySelectorAll(".text-two").forEach((textElement) => {
      gsap.from(textElement, {
        opacity: 0,
        duration: 1,
        ease: "power1.out",
        scrollTrigger: {
          containerAnimation: scrollTimeline,
          trigger: textElement,
          invalidateOnRefresh: true,
          start: "left 70%",
          end: "left 60%",
          scrub: true,
          markers: false /*{
            startColor: "purple",
            endColor: "yellow",
            fontSize: "20px",
          },*/
        },
      });
    });

    // Animation für das Icon
    gsap.from(".icon", {
      rotation: -90,
      duration: 1,
      scrollTrigger: {
        containerAnimation: scrollTimeline,
        trigger: ".icon",
        start: "left 50%",
        end: "left 40%",
        scrub: 1,
        invalidateOnRefresh: true,
        markers: false /*{
          startColor: "yellow",
          endColor: "green",
          fontSize: "25px",
        },*/
      },
    });

    // ScrollTrigger.refresh() bei Resize
    window.addEventListener("resize", () => {
      ScrollTrigger.refresh(); // Sicherheitsmaßnahme, um Positionen neu zu berechnen
    });
  });
</script>

Elementor Free Users:

Paste this into your HTML Widget. CSS Code is already included. 

<style>
    
.scroll-container{
    transition: none;
    overscroll-behavior: none;
    
   /* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/
    
    display:flex !important; 
    width:100% !important;
    Height: 100vh !important;
    overflow: hidden !important; 
    margin: 0px !important; 
    padding: 0px !important;
}

.scroll-content{
    transition: none;
    overscroll-behavior: none;
    
     /* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/
     
    display:flex !important; 
    width: 400vw !important; 
    height: 100vh !important; 
  flex-wrap: nowrap !important; 
  gap: 0 !important; 
  flex-direction: row !important; 
  margin: 0 !important; 
  padding: 0 !important; 
}


/* add the slash and star from code below in case all your settings are fine on mobile. this will overwrite all your settings in the editor*/

.panel {
  display: flex !important; 
  width: 100vw !important; 
  height: 100vh !important; 
  flex-grow: 1 !important; 
  flex-shrink: 0 !important; 
  flex-basis: auto; 
  box-sizing: border-box !important; 
}    
    
</style>



<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/split-type@0.3.4/umd/index.min.js"></script>


 <script>
  document.addEventListener("DOMContentLoaded", () => {
    gsap.registerPlugin(ScrollTrigger);

    let container = document.querySelector(".scroll-content");
    let scrollContainer = document.querySelector(".scroll-container");

    if (!container || !scrollContainer) {
      console.error("Container oder Scroll-Container nicht gefunden. Überprüfe die Klassennamen.");
      return;
    }

    // Timeline for horizontal scrolling and parallax effects
    let scrollTimeline = gsap.timeline({
      scrollTrigger: {
        trigger: scrollContainer,
        pin: true,
        scrub: 1,
        start: "top top",
        end: () => "+=" + container.scrollWidth,
        markers: false,
        invalidateOnRefresh: true,
      },
    });

    // Add Horizontal Scroll to Timeline
    scrollTimeline.to(container, {
      x: () => -(container.scrollWidth - window.innerWidth),
      ease: "none",
    });

    // Zerlege den Text in Buchstaben
    document.querySelectorAll(".panel .text").forEach((textElement) => {
      new SplitType(textElement, { types: "chars" });
    });

    // Animieren der Buchstaben in jedem Panel
    document.querySelectorAll(".panel").forEach((panel) => {
      const chars = panel.querySelectorAll(".char"); // Buchstaben des Panels auswählen

      if (chars.length > 0) {
        gsap.from(chars, {
          y: 200,
          opacity: 1,
          duration: 2,
          ease: "power1.out",
          stagger: 0.05, // Verzögerung zwischen Buchstaben
          scrollTrigger: {
            containerAnimation: scrollTimeline, // Verknüpfe mit horizontalem Scroll
            trigger: panel,
            start: "left 60%",
            end: "left 30%",
            scrub: true,
            markers: false,
        
          },
        });
      }
    });

    // Animieren der Bilder in jedem Panel
    const panels = gsap.utils.toArray(".panel");
    panels.forEach((section, index) => {
      const images = section.querySelectorAll(".img");

      if (images.length > 0) {
        images.forEach((image) => {
          if (index === panels.length - 1) {
            gsap.from(image, {
              x: "+0",
              opacity: 0.5,
              scale: 0.5,
              ease: "power2.out",
              scrollTrigger: {
                containerAnimation: scrollTimeline,
                trigger: image,
                start: "left 100%",
                end: "left 50%",
                scrub: true,
                invalidateOnRefresh: true,
                markers: false /*{
                  startColor: "green",
                  endColor: "orange",
                  fontSize: "14px",
                  indent: 20,
                },*/
              },
            });
          } else {
            gsap.from(image, {
              x: +200,
              opacity: 0.5,
              scale: 0.5,
              scrollTrigger: {
                containerAnimation: scrollTimeline,
                trigger: image,
                start: "left 100%",
                end: "left 0%",
                scrub: 1,
                invalidateOnRefresh: true,
                markers: false /*{
                  startColor: "blue",
                  endColor: "red",
                  fontSize: "12px",
                  indent: 20,
                },*/
              },
            });
          }
        });
      } else {
        console.warn("Keine Bilder gefunden in:", section);
      }
    });

    // Animation für alle Elemente mit der Klasse "text-two"
    document.querySelectorAll(".text-two").forEach((textElement) => {
      gsap.from(textElement, {
        opacity: 0,
        duration: 1,
        ease: "power1.out",
        scrollTrigger: {
          containerAnimation: scrollTimeline,
          trigger: textElement,
          invalidateOnRefresh: true,
          start: "left 70%",
          end: "left 60%",
          scrub: true,
          markers: false /*{
            startColor: "purple",
            endColor: "yellow",
            fontSize: "20px",
          },*/
        },
      });
    });

    // Animation für das Icon
    gsap.from(".icon", {
      rotation: -90,
      duration: 1,
      scrollTrigger: {
        containerAnimation: scrollTimeline,
        trigger: ".icon",
        start: "left 50%",
        end: "left 40%",
        scrub: 1,
        invalidateOnRefresh: true,
        markers: false /*{
          startColor: "yellow",
          endColor: "green",
          fontSize: "25px",
        },*/
      },
    });

    // ScrollTrigger.refresh() bei Resize
    window.addEventListener("resize", () => {
      ScrollTrigger.refresh(); // Sicherheitsmaßnahme, um Positionen neu zu berechnen
    });
  });
</script>
GDPR Cookie Consent with Real Cookie Banner