AnimationsSimpleApril 8, 2026

CSS Sticky Video

A video/image panel sticks at a calculated position near the bottom of the viewport while text scrolls alongside it. No JavaScript required — achieved with position:sticky and calc().

View Full Demo →

We build things that move.

No-5 Studio is a motion-forward design studio based in New York. We work with ambitious brands who want websites that feel alive.

Our process starts with motion. Every project begins with an animation language — a set of principles that define how your brand moves through the digital world.

The result is a website that doesn't just look good. It feels good. It communicates confidence, craft, and intention.

We've shipped projects for fashion brands, nonprofits, agencies, and founders. Every one of them started with a conversation.

index.jsx
import styles from "./styles.module.css";

export default function CssStickyVideo({ heading, body, videoPlaceholder = "#1a1a1a" }) {
  return (
    <section className={styles.section}>
      <div className={styles.text}>
        <h2 className={styles.heading}>{heading}</h2>
        {body.map((para, i) => (
          <p key={i} className={styles.para}>{para}</p>
        ))}
      </div>
      <div
        className={styles.videoSticky}
        style={{ backgroundColor: videoPlaceholder }}
        aria-hidden="true"
      >
        <div className={styles.videoLabel}>Video</div>
      </div>
    </section>
  );
}
styles.module.css
.section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  padding: 4rem 3rem;
  max-width: 1100px;
  margin: 0 auto;
  align-items: start;
}

.text {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding-top: 1rem;
}

.heading {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #1a1a1a;
  line-height: 1.15;
}

.para {
  font-size: 0.9375rem;
  color: #6b6b6b;
  line-height: 1.7;
}

/* The key CSS: sticky positioned at calc(100vh - videoHeight - offset) */
.videoSticky {
  position: sticky;
  top: calc(100vh - 20vw - 172px);
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.videoLabel {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
}

@media (max-width: 768px) {
  .section {
    grid-template-columns: 1fr;
  }

  .videoSticky {
    position: relative;
    top: auto;
  }
}

Apr 27, 2026

ANIMATIONS

Cursor Hover Label

A custom cursor label that follows the mouse and fades in when hovering trigger elements. Uses GSAP quickTo for smooth tracking. Trigger elements use data-cursor-label attributes to set label text. Inspired by portfolio/agency sites like Studio PIC.

Apr 27, 2026

ANIMATIONS

Section Transition 01

GSAP ScrollTrigger-based section transition system. Sibling sections opt into parallax, pin, or reveal modes via data attributes. Supports y offset, overlay opacity, and overlay color per section. Mobile strategy simplifies motion on smaller screens.

Apr 27, 2026

ANIMATIONS

Text Reveal 01

GSAP SplitText-based text reveal system. Text elements opt in with data-reveal-01 and split into lines, words, or characters. Supports load-time reveals, scroll-triggered reveals, scrubbed scroll reveals, and manual split-only mode for custom timelines. Per-element overrides for duration, stagger, delay, ease, and replay behavior.