<h1>ScrollTrigger.matchMedia() Demo</h1>
  <h2>DEPRECATED IN 3.11 IN FAVOUR OF <a href="https://greensock.com/docs/v3/GSAP/gsap.matchMedia()">GSAP.MATCHMEDIA</a></h2>

<section class="gray">
  <p>When the viewport is less than 800px, the "Mobile" div will animate. Otherwise, the "Desktop" one will.</p>
  <div class="mobile">Mobile</div>
  <div class="desktop">Desktop</div>
</section>

<section class="bottom">
  <p><strong>Pretty cool, right?</strong></p>
  <p>Resize your screen. 800px is the break point. It's all dynamic!</p>
  <p>Check out <a href="https://greensock.com/scrolltrigger">ScrollTrigger</a> today. </p>
</section>
body {
  color: white;
  background-color: black;
  text-align: center;
  font-weight: 300;
  font-family: "Signika Negative", sans-serif, Arial;
}
h1 {
  margin: 0;
  padding: 35px 10px;
  font-size: 40px;
  font-weight: 400;
}

.gray {
  background: #222;
  width: 100%;
  height: 100vh;
}
.mobile, .desktop {
  width: 200px;
  height: 100px;
  background: purple;
  position: absolute;
  z-index: 0;
  left: 30%;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  text-align: center;
  font-size: 1.5em;
  font-weight: 400;
  line-height: 100px;
  color: white;
}
.desktop {
  left: 70%;
  background: #88ce02;
  color: black;
}

.gray p {
  color: #ccc;
  font-size: 1.4em;
  margin: 0;
  padding: 30px;
  line-height: 1.4em;
}

.bottom {
  width: 100%;
  color: #ccc;
  text-align: center;
  padding: 150px 30px;
  font-size: 1.5em;
  box-sizing: border-box;
}

.bottom strong {
  color: white;
}

a {
  color: #88ce02;
  text-decoration: none;
  font-weight: 400;
}

a:hover {
  text-decoration: underline;
}

@media (max-width: 799px) { 
  .mobile, .desktop {
    width: 100px;
  }
  h1 {
    font-size: 24px;
  }
  .gray p {
    font-size: 1.2em;
  }
}
gsap.registerPlugin(ScrollTrigger);

// if there are objects that may get inline styles added (like via tweens) that should get reverted, use ScrollTrigger.saveStyles() initially so that the current inline styles are saved for later reversion. It's not always necessary, but it goes well with ScrollTrigger.matchMedia() so we figured it'd make sense to show it here (it's not needed in this demo)
ScrollTrigger.saveStyles(".mobile, .desktop");

/*** Different ScrollTrigger setups for various screen sizes (media queries) ***/
ScrollTrigger.matchMedia({
	
	// desktop
	"(min-width: 800px)": function() {
		// setup animations and ScrollTriggers for screens over 800px wide (desktop) here...
		// ScrollTriggers will be reverted/killed when the media query doesn't match anymore.
    let tl = gsap.timeline({
          scrollTrigger: {
          trigger: ".gray",
          scrub: 1,
          end: "200%",
          pin: true
        }
      });
    tl.to(".desktop", {scale: 2, rotation: 360})
      .to(".desktop", {scale: 1});
  }, 
  
	// mobile
	"(max-width: 799px)": function() {
		// Any ScrollTriggers created inside these functions are segregated and get
		// reverted/killed when the media query doesn't match anymore. 
    let tl = gsap.timeline({ 
        scrollTrigger:{
          trigger: ".gray",
          scrub: 1,
          end: "200%",
          pin: true
        }
      });
    tl.to(".mobile", {scale: 2, rotation: 360})
      .to(".mobile", {scale: 1});
  }, 
  
	// all 
	"all": function() {
		// ScrollTriggers created here aren't associated with a particular media query,
		// so they persist.
	}
  
});


External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.1/gsap.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.1/ScrollTrigger.min.js