04히어로 축소 패럴랙스
히어로 제목이 스크롤하는 동안 점점 작아지고 흐려지며 다음 섹션에 자리를 내준다.
쓰임랜딩 첫 화면, 앱 소개 인트로
scale 1→.6opacity 동반축소+페이드

<main class="stage is-demo">
<div class="heroshrink">
<h2 class="heroshrink__title">축소되는 히어로</h2>
</div>
</main>@use "../../../../site/static/demo-tokens" as *;
// ── 변수 3개. 변형은 이것만 바꾼다 ──────────────────────────
$scale-to: .55; // 다 스크롤했을 때 남는 크기
$duration: $dur-loop; // 데모 왕복 주기
$color: $subject-blue; // 제목 색 (paper 무대라 blue)
@include stage($stage-paper);
.heroshrink {
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.heroshrink__title {
margin: 0;
color: $color;
font: 800 clamp(22px, 8vw, 34px)/1.1 -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
text-align: center;
// ── 실제 사용 코드: 스크롤하는 동안 작아지고 옅어진다 ──
@supports (animation-timeline: scroll()) {
animation: shrink linear both;
animation-timeline: scroll(root);
}
@supports not (animation-timeline: scroll()) { transform: none; opacity: 1; }
}
@keyframes shrink { from { transform: scale(1); opacity: 1; } to { transform: scale(#{$scale-to}); opacity: .25; } }
// ── 데모(.is-demo): 왕복 루프로 흉내 ────────
.stage.is-demo .heroshrink__title { animation: shrink-loop $duration ease-in-out infinite; }
@keyframes shrink-loop {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale($scale-to); opacity: .25; }
}
@media (prefers-reduced-motion: reduce) {
.heroshrink__title, .stage.is-demo .heroshrink__title { animation: none !important; transform: none; opacity: 1; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffffff;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.heroshrink {
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.heroshrink__title {
margin: 0;
color: #2f6df6;
font: 800 clamp(22px, 8vw, 34px)/1.1 -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
text-align: center;
}
@supports (animation-timeline: scroll()) {
.heroshrink__title {
animation: shrink linear both;
animation-timeline: scroll(root);
}
}
@supports not (animation-timeline: scroll()) {
.heroshrink__title {
transform: none;
opacity: 1;
}
}
@keyframes shrink {
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(0.55);
opacity: 0.25;
}
}
.stage.is-demo .heroshrink__title {
animation: shrink-loop 2s ease-in-out infinite;
}
@keyframes shrink-loop {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(0.55);
opacity: 0.25;
}
}
@media (prefers-reduced-motion: reduce) {
.heroshrink__title, .stage.is-demo .heroshrink__title {
animation: none !important;
transform: none;
opacity: 1;
}
}import type { CSSProperties, ReactNode } from "react";
import styles from "./HeroShrink.module.scss";
export type HeroShrinkProps = {
children: ReactNode;
/** 다 스크롤했을 때 남는 크기 (기본 .55) */
scaleTo?: number;
/** 제목 색 */
color?: string;
className?: string;
};
type Vars = CSSProperties & { "--scale-to"?: string; "--color"?: string };
export default function HeroShrink({
children,
scaleTo = 0.55,
color = "#2f6df6",
className = "",
}: HeroShrinkProps) {
const vars: Vars = { "--scale-to": `${scaleTo}`, "--color": color };
return (
<div className={`${styles.wrap} ${className}`} style={vars}>
<h2 className={styles.title}>{children}</h2>
</div>
);
}04 히어로 축소 패럴랙스 — 측정 누적면적 3.955% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · CSS 패럴랙스 스크롤 9종 — AOS·GSAP 없이, JS 0줄
이 데모가 속한 글
CSS 패럴랙스 스크롤 9종 — AOS·GSAP 없이, JS 0줄CSS 패럴랙스 스크롤 아홉 개를 모았습니다. 레이어마다 이동 속도를 다르게 주는 원리 하나로 배경이 내용보다 느리게 움직이는 착시를 만듭니다. 격자에서는 아홉 개가 2초 간격으로 자동 반복되니 먼저 눈으로 훑고 마 이 글의 데모 전부 보기


