04Hero co lại khi cuộn
Tiêu đề hero nhỏ dần và mờ dần trong lúc bạn cuộn, nhường chỗ cho section tiếp theo.
Dùng choMàn hình đầu trang landing, phần mở đầu giới thiệu app
scale 1→.6opacity 동반축소+페이드

<main class="stage is-demo">
<div class="heroshrink">
<h2 class="heroshrink__title">Hero co lại</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 Hero co lại khi cuộn — Diện tích đo được 3.955% · khung hình chuyển động 23/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 hiệu ứng css parallax scrolling, không cần JS
Bài viết chứa demo này
9 hiệu ứng css parallax scrolling, không cần JSCSS parallax scrolling là cách tạo cảm giác chiều sâu khi cuộn trang, bằng cách cho các lớp — nền, chữ, thẻ — di chuyển Xem tất cả demo trong bài này


