<header>
  <h1>gsap.matchMedia()</h1>
  <p class="lead">When the viewport is less than 800px, the "Mobile" &lt;div&gt; will animate. Otherwise, "Desktop" will.</p>
</header>
<section class="gray">
  <div class="mobile">Mobile</div>
  <div class="desktop">Desktop</div>
</section>

<section class="bottom lead">
  <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">GSAP</a> today. </p>
</section>
body {
  color: white;
  background-color: black;
  text-align: center;
  font-weight: 300;
  font-family: "Signika Negative", sans-serif, Arial;
}

header {
  padding: 0 1rem;
  margin: 0 auto;
}

h1 {
  margin: 0;
  padding: 35px 10px;
  font-weight: 400;
}

.gray {
  position: relative;
  background: #222;
  width: 100%;
  height: 100vh;
}

.mobile, .desktop {
  width: 200px;
  height: 100px;
  border-radius: 5px;
  background: var(--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: var(--green);
}

.gray p {
  color: #ccc;
  margin: 0;
  padding: 30px;
}

.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;
  }
}
gsap.registerPlugin(ScrollTrigger);

let mm = gsap.matchMedia(),
    breakPoint = 800;

mm.add({
  // set up any number of arbitrarily-named conditions. The function below will be called when ANY of them match.
  isDesktop: `(min-width: ${breakPoint}px) and (prefers-reduced-motion: no-preference)`,
  isMobile: `(max-width: ${breakPoint - 1}px) and (prefers-reduced-motion: no-preference)`
}, (context) => {
  // context.conditions has a boolean property for each condition defined above indicating if it's matched or not.
  let { isDesktop, isMobile } = context.conditions,
      target = isDesktop ? ".desktop" : ".mobile",
      tl = gsap.timeline({
        scrollTrigger: {
          trigger: ".gray",
          scrub: 1,
          end: "200%",
          pin: true
        }
      });
  tl.to(target, {scale: 2, rotation: 360})
    .to(target, {scale: 1});

  // works for non-ScrollTrigger animations too: 
  gsap.to(target, {backgroundColor: "#2c7ad2", duration: 0.8, ease: "none", repeat: -1, yoyo: true});

  return () => { 
    // optionally return a cleanup function that will be called when the media query no longer matches
  }
}); 
  
Run Pen

External CSS

  1. https://codepen.io/GreenSock/pen/gOWxmWG.css

External JavaScript

  1. https://assets.codepen.io/16327/gsap-latest-beta.min.js
  2. https://assets.codepen.io/16327/ScrollTrigger.min.js