CSS 유틸리티

[CSS Scroll-Driven] JS 0줄로 스크롤에 맞춰 움직이는 진행바·등장 효과

스크롤 이벤트도 IntersectionObserver도 없이, 최신 CSS animation-timeline만으로 진행바를 채우고 요소를 등장시키는 데모.

CSS animation-timelinescroll()view()@supportsprefers-reduced-motion
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약 스크롤 위치를 애니메이션의 "재생 시점"으로 직접 연결해, JavaScript 없이 스크롤에 반응하는 효과를 만듭니다.

이럴 때 필요해요

스크롤 진행바나 "보이면 나타나는" 카드는 흔하지만, 보통 스크롤 이벤트나 IntersectionObserver(요소가 화면에 들어왔는지 감지하는 브라우저 기능)로 JS를 꽤 써야 합니다. 최신 브라우저라면 이걸 CSS 몇 줄로 끝낼 수 있어요.

어떻게 동작하나

  1. animation-timeline: scroll()은 "스크롤 0%~100%"를 애니메이션의 0%~100%로 연결 진행바가 스크롤만큼 채워집니다.

  2. animation-timeline: view()는 "그 요소가 뷰포트를 지나가는 동안"을 타임라인으로 삼아, 화면에 들어올 때 fade+slide로 등장시킵니다.

  3. 미지원 브라우저는 @supports로 그냥 보이게 폴백하고, prefers-reduced-motion이면 애니메이션을 끕니다.

핵심은 이거예요

애니메이션의 진행을 "시간"이 아니라 "스크롤/가시성"에 묶는다는 발상입니다. 키프레임은 똑같고, 무엇이 재생을 끌고 가느냐만 바뀝니다.

놓치기 쉬운 것

  • 아직 모든 브라우저가 지원하진 않아 폴백이 필수입니다.

  • 모션에 민감한 사용자를 위해 prefers-reduced-motion을 존중해야 합니다.

  • 스크롤러 기준(root/nearest)을 잘못 잡으면 애니메이션이 움직이지 않습니다.

이런 곳에 써요

  • 문서블로그 상단의 읽기 진행바

  • 랜딩 페이지 섹션의 등장(reveal) 효과

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { CssScrollDrivenDemo } from "./-components/CssScrollDrivenDemo";

export const metadata: Metadata = {
  title: "CSS 스크롤 연동 애니메이션 (데모)",
  description:
    "JavaScript 0줄. 최신 CSS animation-timeline: scroll() / view() 만으로 스크롤 진행바 + 뷰포트 진입 reveal을 구현합니다.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    // data-demo-embed-fixed="720" — 임베드 iframe 높이를 720px로 고정.
    // 이 데모는 스크롤이 핵심이라 자동 높이(콘텐츠 전체 높이)로 펼치면 스크롤이 사라지므로,
    // 고정 높이를 줘서 iframe 안에서 자체 스크롤이 일어나게 한다.
    <main
      data-demo-embed-fixed="720"
      className="min-h-[100dvh] bg-white"
    >
      <CssScrollDrivenDemo />
    </main>
  );
}
20조회수

댓글