Motion & Effects
CSS motion has evolved dramatically. Today you can create scroll-linked animations, glass morphism cards, and clip-path reveals — all without a single line of JavaScript. The trick is learning how to describe animation in natural language.
Keyframe animations — describe the states
Instead of thinking in CSS @keyframes, describe what you see happening:
버튼에 pulse 효과 줘.
천천히 커졌다가 (scale 1.15) 원래 크기로 돌아오는 루프.
opacity도 같이 살짝 변해서 빛나는 느낌.
2초 주기, ease-in-out.
AI generates the @keyframes block. You just described the visual.
CSS Scroll-driven animations — no JS needed
The new animation-timeline: scroll() API lets you tie any CSS animation to scroll progress — no JavaScript:
스크롤 진행률 바 만들어줘.
화면 상단 고정, 높이 3px, accent 색상.
페이지 스크롤에 따라 width 0% → 100%.
animation-timeline: scroll() 사용.
This is a massive shift: effects that once required a scroll listener are now pure CSS. Browser support is growing fast (Chrome, Edge, Firefox) — always add a JS fallback for Safari.
Clip-path reveal
Clip-path cuts elements into shapes and animates the cut smoothly:
텍스트 reveal 효과:
clip-path: inset(0 100% 0 0) 에서 inset(0 0% 0 0) 로 전환.
0.6초, cubic-bezier(0.16, 1, 0.3, 1) — springy feel.
버튼 클릭으로 트리거.
The easing cubic-bezier(0.16, 1, 0.3, 1) is the “Expo Out” curve — it starts fast, finishes with a satisfying snap.
Glass morphism
Glass cards need a few specific values to look right:
유리 카드 컴포넌트:
배경: linear-gradient(135deg, #667eea, #764ba2) 위에 올려줘.
카드 자체: backdrop-filter: blur(16px),
background: rgba(255,255,255,0.2),
border: 1px solid rgba(255,255,255,0.3),
border-radius 16px.
The key: backdrop-filter blurs what’s behind the element — so the card must have a semi-transparent background, not opaque.
Shimmer hover effect
A sweeping light highlight on hover is one of the most polished button effects. It uses a ::after pseudo-element:
버튼 hover시 빛이 왼쪽에서 오른쪽으로 스쳐가는 shimmer 효과.
::after pseudo-element 사용.
linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent).
position: absolute, overflow: hidden on button.
Key prompting tip
When prompting for animations, always specify: what changes, from what to what, how fast, what triggers it, and what the easing feels like (springy, smooth, sharp). These five points give AI everything it needs.
The demo shows all five effects live — keyframe pulse, scroll progress bar, clip-path reveal, glass card, and shimmer button.
CSS 모션은 극적으로 발전했습니다. 오늘날 스크롤 연동 애니메이션, 유리 형태소 카드, clip-path 리빌을 JavaScript 한 줄 없이 만들 수 있습니다. 핵심은 자연어로 애니메이션을 설명하는 법을 배우는 것입니다.
키프레임 애니메이션 — 상태 설명
CSS @keyframes를 생각하는 대신, 보이는 것을 설명하세요:
버튼에 pulse 효과 줘.
천천히 커졌다가 (scale 1.15) 원래 크기로 돌아오는 루프.
opacity도 같이 살짝 변해서 빛나는 느낌.
2초 주기, ease-in-out.
AI가 @keyframes 블록을 생성합니다.
CSS 스크롤 기반 애니메이션 — JS 불필요
새로운 animation-timeline: scroll() API로 JavaScript 없이 CSS 애니메이션을 스크롤 진행률에 연결합니다:
스크롤 진행률 바 만들어줘.
화면 상단 고정, 높이 3px, accent 색상.
페이지 스크롤에 따라 width 0% → 100%.
animation-timeline: scroll() 사용.
Clip-path 리빌
텍스트 reveal 효과:
clip-path: inset(0 100% 0 0) 에서 inset(0 0% 0 0) 로 전환.
0.6초, cubic-bezier(0.16, 1, 0.3, 1).
버튼 클릭으로 트리거.
Shimmer 호버 효과
버튼 hover시 빛이 왼쪽에서 오른쪽으로 스쳐가는 shimmer 효과.
::after pseudo-element 사용.
linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent).
데모는 키프레임 펄스, 스크롤 진행률 바, clip-path 리빌, 유리 카드, shimmer 버튼 — 다섯 가지 효과를 라이브로 보여줍니다.
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: #fff;
color: #111;
line-height: 1.6;
}
/* ========================
Scroll Progress Bar
======================== */
.scroll-progress {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: #2563eb;
z-index: 100;
width: 0%;
/* Native CSS scroll-driven animation — Chrome/Edge/Firefox */
animation: grow-width linear both;
animation-timeline: scroll();
}
@keyframes grow-width {
from { width: 0%; }
to { width: 100%; }
}
/* ========================
Nav
======================== */
nav {
padding: 16px 40px;
border-bottom: 1px solid #e5e5e5;
}
nav a {
color: #2563eb;
text-decoration: none;
font-size: 0.875rem;
}
nav a:hover { text-decoration: underline; }
/* ========================
Layout
======================== */
main {
max-width: 860px;
margin: 0 auto;
padding: 40px 40px 120px;
}
.page-header {
margin-bottom: 56px;
}
.page-header h1 {
font-size: 2rem;
font-weight: 700;
letter-spacing: -0.02em;
margin-bottom: 8px;
}
.page-desc {
color: #444;
font-size: 1rem;
}
/* ========================
Effect Cards
======================== */
.effect-card {
border: 1px solid #e5e5e5;
border-radius: 12px;
padding: 28px 32px;
margin-bottom: 32px;
}
.effect-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: #888;
margin-bottom: 6px;
}
.effect-title {
font-size: 1.2rem;
font-weight: 600;
margin-bottom: 10px;
}
.effect-desc {
font-size: 0.9rem;
color: #444;
line-height: 1.6;
margin-bottom: 24px;
}
.effect-desc code {
font-family: 'Menlo', 'Monaco', monospace;
font-size: 0.85em;
background: #f0f0f0;
padding: 2px 5px;
border-radius: 4px;
}
/* Demo areas */
.demo-area {
background: #f8f8f8;
border-radius: 8px;
border: 1px solid #e5e5e5;
padding: 32px 24px;
}
.demo-area--center {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
.demo-area--code {
padding: 20px 24px;
}
.demo-area--code pre {
font-family: 'Menlo', 'Monaco', monospace;
font-size: 0.78rem;
color: #444;
line-height: 1.7;
overflow-x: auto;
white-space: pre;
}
.demo-area--code code {
font-family: inherit;
}
.demo-area--reveal {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 20px;
}
/* ========================
1. Pulse Circle
======================== */
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.15);
opacity: 0.7;
}
}
.pulse-circle {
width: 60px;
height: 60px;
border-radius: 50%;
background: #2563eb;
animation: pulse 2s ease-in-out infinite;
}
.demo-label {
font-size: 0.75rem;
color: #888;
font-family: 'Menlo', 'Monaco', monospace;
}
/* ========================
3. Clip-path Reveal
======================== */
.reveal-wrapper {
overflow: hidden;
border-radius: 4px;
}
.reveal-text {
font-size: 2.5rem;
font-weight: 700;
letter-spacing: -0.03em;
color: #111;
clip-path: inset(0 100% 0 0);
transition: clip-path 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal-text.is-revealed {
clip-path: inset(0 0% 0 0);
}
.play-btn {
padding: 10px 20px;
background: #111;
color: #fff;
border: none;
border-radius: 6px;
font-size: 0.875rem;
font-family: inherit;
cursor: pointer;
transition: background 0.15s;
}
.play-btn:hover {
background: #2563eb;
}
/* ========================
4. Glass Morphism
======================== */
.demo-area--glass {
background: linear-gradient(135deg, #667eea, #764ba2);
padding: 48px 32px;
display: flex;
align-items: center;
justify-content: center;
}
.glass-card {
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 16px;
padding: 28px 32px;
max-width: 320px;
width: 100%;
}
.glass-eyebrow {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.7);
margin-bottom: 6px;
}
.glass-title {
font-size: 1.5rem;
font-weight: 700;
color: #fff;
margin-bottom: 8px;
}
.glass-body {
font-size: 0.9rem;
color: rgba(255, 255, 255, 0.85);
line-height: 1.5;
}
/* ========================
5. Shimmer Button
======================== */
@keyframes shimmer-sweep {
from { left: -100%; }
to { left: 100%; }
}
.shimmer-btn {
position: relative;
overflow: hidden;
padding: 14px 32px;
background: #111;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1rem;
font-family: inherit;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.shimmer-btn::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 60%;
height: 100%;
background: linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.3) 50%,
transparent 100%
);
}
.shimmer-btn:hover::after {
animation: shimmer-sweep 0.5s ease-in-out;
}
.shimmer-btn:hover {
background: #2563eb;
}
/* ========================
Mobile
======================== */
@media (max-width: 640px) {
main {
padding: 24px 20px 80px;
}
.effect-card {
padding: 20px 20px;
}
}