모션 느낌 (Motion feels)
대부분의 사람들은 이징 곡선의 이름을 말할 수 없지만, 원하는 느낌(차분한, 힘 있는, 고급스러운, 장난기 있는)은 정확히 알고 있습니다. 그런데 그런 단어들은 수많은 곡선에 해당되기 때문에, AI가 추측하게 되고, 결국 '너무 빠르다', '덜 튀게'와 같은 수정 작업이 반복됩니다. 이 스킬은 사람과 당신이 공유할 수 있는 하나의 이름 세트를 제공하며, 각 이름은 정확한 값과 연결되어 있습니다. 그들은 느낌으로 말하고, 당신은 숫자로 처리합니다.
이 스킬은 웹사이트(마케팅, 포트폴리오, 콘텐츠, 쇼핑몰)를 위해 작성되었습니다. 앱이나 제품 UI에도 동일한 느낌을 사용할 수 있으며, 각 속도의 빠른 쪽 끝을 사용하세요.
세 가지 부분으로 구성됩니다:
- 느낌(Feel): 어떻게 움직이는가. 속도와 이징 곡선의 조합. 아래 14가지 느낌이 있습니다.
- 효과(Effect): 무엇이 움직이는가. 마스크 리빌(mask reveal), 패럴랙스(parallax), 마키(marquee) 등.
references/feels.md를 참조하세요. - 다이얼(Dials): 느낌을 조정합니다: 속도, 정지, 오버슈트, 스태거, 거리, 지연, 트리거, 강도.
곡선이 아닌 느낌으로 대화하세요
상대방은 모션 관련 용어를 전혀 모를 수 있으며, 알 필요도 없습니다.
- 이징(easing), 곡선(curve), 베지어(bezier), 밀리초(millisecond)를 선택하라고 요청하지 마세요. 대신 일상생활의 비유를 들어 느낌에 대해 물어보세요: "유리잔을 내려놓듯 부드럽게 착지해야 할까요, 아니면 스프링처럼 살짝 지나쳤다가 안정될까요?"
- 느낌을 어떻게 만드는지가 아니라 어떻게 보이는지로 설명하세요: "빠르게 시작해서 미끄러지듯 멈춤"이라고 말하고, "power4.out"이라고 말하지 마세요.
- 느낌 이름은 선택적인 바로가기입니다. 대화 중에 살짝 언급하세요 ("이 느낌을 고급스러운(Luxurious) 이라고 부르겠습니다") 그래야 그들이 재사용할 수 있습니다. 절대 요구하거나 그들의 표현을 교정하지 마세요.
- 숫자는 코드에 넣고, 빌드하거나 검토할 사람을 위해 짧은 한 줄을 추가하세요: "개발자용: 1.2초,
cubic-bezier(0.22, 1, 0.36, 1)." 아무도 그 코드로 빌드하지 않을 경우(예: 상대방이 방향만 선택하는 경우) 그 줄은 생략하세요. - 이 파일의 단어는 당신을 위한 것이지, 그들을 위한 것이 아닙니다. 다이얼 이름과 CSS 용어는 답변에 포함하지 마세요. 대신 "끝에 약간 튐" (오버슈트), "하나씩 차례로" (스태거), "얼마나 멀리 이동하는지" (거리), "얼마나 부드럽게 멈추는지" (정지), "얼마나 많이 한 번에 움직이는지" (강도), "어디에서 커지는지" (원점), "애니메이션을 끈 사람들을 위해" (축소 모션)과 같이 말하세요.
- 한 줄로 번역한 후, 바로 빌드하세요. 강의하거나 작업을 지연시키지 마세요. 유일한 예외는 아래 표에서 "질문(ask)"으로 표시된 단어로, 이 경우 먼저 간단한 질문을 하나 합니다.
- 설명보다 보여주는 것이 낫습니다. 그들이 말로 표현하지 못할 때는 데모 페이지(
assets/feels-demo.html, 아무 브라우저에서나 열어보세요)를 제공하거나, 빠른 A/B 토글을 만들어 선택하게 하세요.
14가지 느낌 (The 14 feels)
| 느낌 | 모양새 | 속도 | CSS | GSAP |
|---|---|---|---|---|
| 깔끔함 (Crisp) | 전등 스위치: 즉각적, 깔끔한 정지 | 150 ms | cubic-bezier(0.33, 1, 0.68, 1) | power2.out |
| 경쾌함 (Snappy) | 튀어나와서 단단히 착지 | 300 ms | cubic-bezier(0.16, 1, 0.3, 1) | expo.out |
| 탄력 있음 (Springy) | 빠르고, 약간 지나쳤다가 안정됨 | 600 ms | spring, 바운스 0.3 (CSS에서는 linear()) | 스프링 없음; 가장 가까움 back.out(1.2) |
| 부드러움 (Smooth) | 미닫이문: 부드럽게 시작, 부드럽게 정지 | 500 ms | cubic-bezier(0.65, 0, 0.35, 1) | power2.inOut |
| 온화함 (Gentle) | 스며들어 들어와서 서서히 멈춤 | 700 ms | cubic-bezier(0.61, 1, 0.88, 1) | sine.out |
| 고급스러움 (Luxurious) | 빠르게 시작, 길고 느린 활강 후 정지 | 1.2 s | cubic-bezier(0.22, 1, 0.36, 1) | power4.out |
| 둥실함 (Floaty) | 깃털: 느리고 일정하며, 시작과 끝이 뚜렷하지 않음 | 2 s | cubic-bezier(0.37, 0, 0.63, 1) | sine.inOut |
| 극적임 (Dramatic) | 극장 커튼: 천천히 올라가다가 빠르게 열리고 안정됨 | 1.2 s | cubic-bezier(0.87, 0, 0.13, 1) | expo.inOut |
| 태엽 감기 (Wind-up) | 새총: 먼저 뒤로 당겼다가 끝을 지나침 | 800 ms | cubic-bezier(0.68, -0.6, 0.32, 1.6) | back.inOut(1.7) |
| 팝 (Pop) | 끝을 뛰어넘었다가 한 번 돌아옴 | 450 ms | cubic-bezier(0.34, 1.56, 0.64, 1) | back.out(1.7) |
| 탄성 (Elastic) | 젤리: 몇 번 흔들리다가 안정됨 | 1 s | linear() from elastic.out | elastic.out(1, 0.3) |
| 바운스 (Bounce) | 공이 착지하는 모습 | 900 ms | linear() from bounce.out | bounce.out |
| 기계적 (Mechanical) | 컨베이어 벨트: 전체적으로 동일한 속도 | 1 s | linear | none |
| 계단식 (Stepped) | 플립북: 프레임별로 점프 | 900 ms | steps(6) | steps(6) |
느낌은 어떤 속도에서도 그 곡선을 유지합니다: "400ms의 탄력 있음(Springy)"은 더 빠르게 움직이는 Springy 모양입니다. 일반 CSS에서 스프링, 탄성, 바운스는 곡선에서 샘플링된 linear() 목록입니다. 바로 붙여넣을 수 있는 값은 references/feels.md("Ready-to-paste code")에 있습니다. 스프링 "바운스"는 SwiftUI와 Motion에서 사용하는 0–1 값입니다(감쇠 비율 = 1 - 바운스).
작업 방법 (How to work)
- 먼저 요소를 확인하세요: 얼마나 자주 보이는지, 그리고 인터페이스 부분인지 쇼케이스 모션인지 (아래 "느낌을 고르기 전에"). 이를 통해 모션을 줄이거나 없앨 수 있습니다.
- 그들의 말을 아래 "일상적인 단어" 표를 사용하여 느낌 + 다이얼 + 효과로 번역하세요. 두세 가지 느낌이 맞다면, 간단한 질문을 하나 하거나 (또는 A/B 토글을 보여주세요).
- 빌드하기 전에 계획을 한 줄로 말하세요. 예: "헤드라인이 스크롤에 맞춰 부드럽게 올라오며 천천히 정착합니다. 한 번만 (느낌: 고급스러움(Luxurious))." 그들은 아무것도 만들어지기 전에 방향을 바꿀 수 있습니다.
- duration, delay, easing을 CSS 변수나 하나의 설정 객체 (
--motion-dur,--motion-ease,--motion-stagger)로 사용하여 빌드하세요. 그러면 모든 조정이 숫자 하나만 바꾸면 됩니다. "빌드 규칙"을 따르세요. - 개발자를 위한 값과 함께 평범한 말로 보고하세요. 변경 사항이 있으면 이전 → 이후를 보여주세요: "약간 더 느리게: 1.2초 → 1.8초". 이전 값을 유지하여 "되돌리기"가 정확히 복원되도록 하세요.
- 일관성을 유지하세요: 사이트의 느낌이 확정되면, 프로젝트의 디자인 토큰에 모션 팔레트(아래 참조)로 저장하여 모든 섹션이 동일하게 움직이도록 제안하세요.
전체 사이트를 위한 모션 팔레트 (A motion palette for the whole site)
좋은 사이트는 14가지가 아닌 2~3가지 느낌을 사용합니다: 인터페이스 부분용 하나, 쇼케이스 순간용 하나, 그리고 가끔 악센트용 하나. 누군가 모션을 전혀 설명할 수 없을 때, 브랜드를 세 단어로 말해달라고 하고 한 줄로 팔레트를 제안하세요.
| 브랜드가 느껴지는 방식 | 쇼케이스 (Showcase) | 인터페이스 (Interface) | 악센트 (Accent) |
|---|---|---|---|
| 차분함, 신뢰감, 배려 (헬스케어, 금융, 법률) | 온화함 (Gentle) | 깔끔함 (Crisp) | — |
| 프리미엄, 에디토리얼 (패션, 건축, 호텔) | 고급스러움 (Luxurious) | 깔끔함 (Crisp) | 첫 로드 시 극적임 (Dramatic) |
| 대담함, 빠름, 기술적 (스타트업, SaaS, 스포츠) | 경쾌함 (Snappy) | 깔끔함 (Crisp) | 팝 (Pop) |
| 친근함, 장난기 (어린이, 음식, 소비자 앱) | 탄력 있음 (Springy) | 경쾌함 (Snappy) | 팝 (Pop) 또는 바운스 (Bounce) |
| 창의적, 표현적 (스튜디오, 포트폴리오, 에이전시) | 고급스러움 (Luxurious) 또는 극적임 (Dramatic) | 경쾌함 (Snappy) | 태엽 감기 (Wind-up) |
| 꿈결 같음, 자연적 (웰니스, 뷰티, 명상) | 루프는 둥실함 (Floaty), 콘텐츠는 온화함 (Gentle) | 깔끔함 (Crisp) | — |
| 레트로, 날것 (게임, 음악, 브루탈리즘) | 계단식 (Stepped) | 깔끔함 (Crisp) | 기계적 마키 (Mechanical marquees) |
느낌을 고르기 전에 (Before picking a feel)
얼마나 자주 보이나요?
한 번 즐겁게 하는 모션은 열 번째에는 방해가 됩니다. 방문자가 요소를 만나는 빈도에 따라 모션의 양을 조정하세요.
| 얼마나 자주 | 예시 | 모션 |
|---|---|---|
| 모든 페이지, 모든 방문 시 | 네비게이션 링크, 헤더, 버튼, 푸터 링크, 폼 필드 | 작고 빠르게: 깔끔함 (Crisp), 또는 색상 변경만. 키보드 포커스는 즉시 포커스 링을 보여주며 움직임이 없습니다. 이들에 대한 진입 효과(예: 로드 시 네비게이션이 슬라이드인)는 첫 페이지 보기에서만 재생됩니다. |
| 모든 클릭 시 | 페이지 전환 | 짧게: 600ms 이하, 브랜드가 느리고 프리미엄이더라도 |
| 페이지당 한 번 | 히어로, 섹션 리빌, 케이스 스터디 카드, 통계 카운트업 | 전체 느낌 적용. 스크롤 리빌은 한 번만 재생되며, 다시 스크롤해도 재생되지 않습니다. |
| 방문당 한 번 | 인트로 로더, 첫 로드 히어로 순간 | 극적임 (Dramatic)과 즐거움을 위한 여유 공간. 로더는 첫 페이지 보기에서만 실행합니다. |
팔레트의 악센트는 컨트롤이 아닌 결과에 적용됩니다: 장바구니 추가 버튼 누름은 빠르게 유지하고(깔끔함), 장바구니 개수가 팝(Pop) 되는 식입니다.
누군가 모든 페이지에 표시되는 요소에 느린 느낌을 요청하면, 빠른 버전으로 빌드하고 한 줄로 전환 방법을 알려주세요: "네비게이션 링크는 모든 페이지에 있으므로 빠르게 유지했습니다. 느린 버전은 숫자 하나만 바꾸면 됩니다." 답변을 기다리지 마세요; 그들의 선택입니다.
인터페이스 부분인가요, 쇼케이스인가요?
- 인터페이스 부분: 방문자는 무언가를 하려고 합니다. 네비게이션 드롭다운, 모바일 메뉴, 탭, 아코디언, 모달, 툴팁, 폼 피드백, 필터. 느낌과 관계없이 300ms 이하로 유지하세요. 모바일 메뉴와 모달은 최대 400ms까지 가능합니다. 종료는 진입의 약 75% 속도로 실행합니다: 닫힌 상태에는 더 짧은 duration을 적용하세요.
- 쇼케이스 모션: 분위기를 조성합니다. 히어로, 섹션 리빌, 이미지 리빌, 마키, 배경 루프, 첫 로드 순간. 느낌 자체의 속도가 적용되며, 긴 것도 괜찮습니다.
요소별 기본값 (느낌이 주어지지 않았을 때)
여기의 속도는 느낌 자체의 속도를 대체합니다. "싸구려 같아", "너무 튀어"와 같은 피드백은 이 기본값을 무효화합니다.
| 요소 | 느낌 | 속도 |
|---|---|---|
| 버튼, 링크, 토글, 호버, 툴팁 | 깔끔함 (Crisp) | 150 ms |
| 네비게이션 드롭다운, 탭, 카드 호버 | 경쾌함 (Snappy) | 250 ms |
| 아코디언, FAQ | 부드러움 (Smooth) | 300 ms |
| 모바일 메뉴, 모달, 서랍(Drawer), 시트(Sheet) | 탄력 있음 (Springy) | 400 ms |
| 드래그 앤 릴리즈 | 탄력 있음 (Springy) | 600 ms |
| 슬라이드, 캐러셀, 화면을 가로지르는 것들 | 부드러움 (Smooth) | 500 ms |
| 텍스트 및 이미지 리빌 (24px 페이드업, 60–80ms 스태거) | 팔레트의 쇼케이스 느낌; 단서가 없으면 경쾌함 (Snappy) | 느낌 자체의 속도 |
| 페이지 전환 | 부드러움 (Smooth) | 600 ms |
| 히어로 순간, 첫 로드 | 극적임 (Dramatic) | 1.2 s |
| 배경 루프, 주변 형태(Ambient shapes) | 둥실함 (Floaty) | 2 s |
| 성공 상태, 배지 | 팝 (Pop) | 450 ms |
| 로더, 마키, 스크롤 기반 모션 | 기계적 (Mechanical) | 필요에 따라 |
일상적인 단어 (Everyday words)
이 표를 사용하여 번역하세요. 왼쪽 열은 사람들이 실제로 말하는 내용이며, 모션 지식이 전혀 필요하지 않습니다. 긴 대화에서는 각 번역을 한 번 보여준 후, 조용히 적용하세요.
단어 → 느낌
| 그들이 말할 때 | 읽어야 할 느낌 | 질문할 경우 |
|---|---|---|
| 프리미엄, 비싼, 우아한, 클래스 있는, 하이엔드, 럭셔리, "잡지처럼", "느리고 자신감 있는" | 고급스러움 (Luxurious) | — |
| 부드러운, 유체 같은, 버터 같은, 매끄러운, 실키한, "미끄러지듯" | 부드러움 (Smooth) (가로지르는) 또는 온화함 (Gentle) (나타나는) | 요소가 명확하지 않을 때: "시작부터 끝까지 균일하게 미끄러지나요, 아니면 부드럽게 나타나서 서서히 멈추나요?" |
| 부드러운, 차분한, 편안한, 조용한, 아늑한, 따뜻한, "화려하지 않은" | 온화함 (Gentle) | — |
| 미묘한, 거의 눈에 띄지 않는, "사람들이 눈치채지 못하게" | 깔끔함 (Crisp) (인터페이스) 또는 온화함 (Gentle) (콘텐츠) | — |
| 꿈결 같은, 공기 같은, 떠다니는, 무중력의, "깃털처럼", "물속처럼" | 둥실함 (Floaty) | — |
| 빠른, 재빠른, 반응성, 즉각적인, 클릭감 있는, 타이트한, "전등 스위치처럼" | 깔끔함 (Crisp) (작은 것) 또는 경쾌함 (Snappy) (큰 것) | 크기가 명확하지 않음 |
| 강렬한, 에너지 넘치는, 대담한, 자신감 있는, 강한, "단단히 착지하는", "태도 있는" | 경쾌함 (Snappy) | — |
| 자연스러운, 물리적인, 살아있는, "폰 앱처럼", "실제 물체처럼" | 탄력 있음 (Springy) | — |
| 재미있는, 장난기 있는, 귀여운, 친근한, 건방진, 행복한 | 팝 (Pop), 탄력 있음 (Springy) 또는 탄성 (Elastic) | 거의 항상: "끝을 살짝 넘어갔다가 돌아오는 느낌, 부드럽게 탄력 있게 안정되는 느낌, 아니면 젤리처럼 흔들리는 느낌?" |
| 통통 튀는 | 바운스 (Bounce) (착지 후 튐) 또는 팝 (Pop) / 탄력 있음 (Springy) (살짝 지나치고 안정됨) | 항상: "공이 착지해서 튀는 것처럼 바운스할까요, 아니면 살짝 지나쳤다가 안정될까요?" |
| 젤리 같은, 흔들리는, 고무 같은, 말랑말랑한, 꿈틀거리는 | 탄성 (Elastic) | — |
| 영화 같은, 장대한, "영화처럼", 강력한, 무거운, "와우 모먼트", 큰 리빌 | 극적임 (Dramatic) | — |
| 만화 같은, "먼저 감았다가", "새총처럼" | 태엽 감기 (Wind-up) | — |
| 로봇 같은, 일정한, 꾸준한, "컨베이어 벨트처럼", 티커 | 기계적 (Mechanical) | — |
| 레트로, 끊기는, 스톱모션, 픽셀, 글리치, "옛날 비디오 게임처럼", 플립북 | 계단식 (Stepped) | — |
| 모던한, 멋진, 깔끔한, "팝 하게 만들어 줘", "좋아 보이게", "애니메이션 좀 넣어", "살아 움직이게 해줘" | 그 자체로는 없음 | 항상: 문맥에 맞는 느낌 3가지를 평범한 말로 제안하거나, 브랜드를 세 단어로 표현해 달라고 요청 ("팝 하게"는 Pop 느낌을 의미할 수도 있고, 그냥 "더 눈에 띄게"를 의미할 수도 있음) |
피드백 → 다이얼
| 그들이 말할 때 | 변경 사항 |
|---|---|
| 너무 빠름, 급함, "눈 깜빡하면 놓침", "볼 수가 없어" | 속도 × 1.5 |
| 너무 느림, 굼뜸, 지연됨, "영원히 걸림", "기다리고 있어" | 속도 ÷ 1.5. 인터페이스 부분의 경우 300ms 제한도 확인하세요. |
| 갑작스러움, 거침, 울퉁불퉁, "쿵 하고 박힘", "너무 갑자기 멈춤" | 정지(Stop): 더 부드럽게, 한 단계씩 power2.out → power3.out → power4.out → expo.out (CSS 값은 references/feels.md에) |
| 질척함, "끝에서 질질 끎", "기어감", "안정되는 데 너무 오래 걸림" | 정지(Stop): 더 단단하게 (꼬리 더 짧게), 또는 더 빠르게 |
| 약함, 생명력 없음, "더 강한 타격이 필요", "착지감이 없어" | 정지 더 단단하게 + 속도 ÷ 1.5, 또는 경쾌함 (Snappy)으로 전환 |
| 너무 튐, "너무 과함", 싸구려 같은, 유치함, "오버임" | 오버슈트 한 단계 낮춤: 팝 cubic-bezier(0.34, 1.56, 0.64, 1) → 약간 cubic-bezier(0.34, 1.4, 0.64, 1) → 없음 (경쾌함) |
| 싸구려 같아 | 보통 너무 많은 움직임: 거리(Distance) 낮춤 및 오버슈트(Overshoot) 낮춤; 느리다면 속도 ÷ 1.5 |
| 덜컹거림, 지터링, "갑자기 튀어나와" | 아무것도 없는 상태에서 커지거나 오버슈트함: scale(0.95)에서 시작 (빌드 규칙), 오버슈트 한 단계 낮춤, 거리(Distance) 낮춤 |
| 뻣뻣함, 로봇 같음, 죽은 듯함, "더 생동감이 필요" | 오버슈트 한 단계 높임, 또는 탄력 있음 (Springy)으로 전환 |
| 평범함, 지루함, "아무 일도 안 일어남", "눈에 띄지 않아" | 스태거(Stagger) 높임, 또는 거리(Distance) 높임 |
| 복잡함, 산만함, "너무 많은 일이 벌어짐", 짜증남 | 강도(Intensity) 낮춤, 스태거(Stagger) 낮춤. 짜증나는 경우는 너무 자주 보여서일 수 있음: "얼마나 자주 보이나요?" 확인 |
| "어지러워", "멀미 나" | 패럴랙스, 큰 크기 조정, 먼 거리 이동 제거; 축소 모션 폴백 확인 |
| 너무 늦게 / 너무 일찍 시작함 | 지연(Delay) 낮춤 / 높임 (100ms 단위) |
| 어색함, "맞지 않음", "뭔가 잘못됨" | 추측하지 마세요: "속도 때문인가요, 시작 방식 때문인가요, 정지 방식 때문인가요, 아니면 끝의 작은 튐 때문인가요?" 또는 두 버전을 나란히 보여주세요 |
빌드 규칙 (Build rules)
transform으로 이동하고,opacity로 페이드 처리하세요.width,height,top,left또는margin에는 애니메이션을 적용하지 마세요. 스크롤 중에 버벅입니다. 아코디언의 경우grid-template-rows: 0fr → 1fr이 허용된 예외입니다 (콘텐츠는min-height: 0; overflow: hidden이 있는 내부 래퍼에 위치). 절대transition: all을 사용하지 말고, 속성을 명시하세요.- 아무것도 없는 상태에서 크기를 키우지 마세요. 스케일 인은
scale(0.95)와opacity: 0에서 시작하세요 (더 큰 팝은 0.9). 절대scale(0)에서 시작하지 마세요. - 커질 때는 원점을 지정하세요.
transform-origin에 따라 커집니다: 왼쪽에서 커지는 메뉴는left top, 카드는center center등. 기본값center에 의존하지 마세요. - 지속 시간을 일관되게 유지하세요. 페이지의 모든 요소에 하나의 지속 시간을 사용하기보다,
--motion-dur과--motion-ease라는 CSS 사용자 정의 속성 두 개를 선언하고, 요소에는 이것들만 참조하세요. 그러면 조정이 단일 지점 업데이트가 됩니다. JS 애니메이션에는 같은 값을 내보내는 설정 객체를 사용하세요. - 지연은 CSS에서 승계되지 않습니다. 개별적으로 설정하세요.
- 시퀀스에는 스태거(stagger)를 사용하고, 지연은 피하세요. 스태거는 모든 항목에 균일한 간격을 유지합니다. 예:
animation-delay: calc(var(--i, 0) * 60ms)또는 GSAPstagger: 0.06. 지연은 다른 애니메이션이 완료될 때까지 기다려야 할 때만 사용하세요. - 애니메이션 채우기 모드는 기본값
none입니다.animation-fill-mode: forwards는 요소가 최종 상태를 유지하지 못하게 할 수 있습니다. 대신 초기 및 최종 스타일을 정적으로 설정하고,animation-fill-mode: both를 사용하세요. - 이동 거리는 콘텐츠 유형에 따라 다릅니다. 텍스트는 20–48px(보통 24px) 이동해야 합니다. 이미지는 자연스러운 프레임 내에서 50–150px 이동할 수 있습니다. 카드는 3D 공간에서만 이동합니다(그렇지 않으면 평평해 보입니다). 모든 거리는 CSS 변수
--motion-distance여야 합니다. - 마키(Marquee)는 빠르고 끊김 없이 유지하세요. 마키 속도는 콘텐츠 너비에 맞춰 조정되어야 하며, 동일한 속도(기계적 느낌)를 유지합니다. 마키는 스크롤바, 포커스 또는 터치 상호작용에서 멈춰야 합니다.
- 시차(Parallax)는 움직이지 않는 요소와 같은 속도로 움직입니다. 시차 속도는 여러분과 디자이너가 정합니다. 대부분의 콘텐츠 사이트에서 0.1–0.2는 미묘하고, 0.5는 극적입니다.
- 감소된 모션 (Reduced motion). 모든 모션은
prefers-reduced-motion: reduce미디어 쿼리를 존중하여 부드러운 페이드로 대체되어야 하며, 이동이나 크기 조정이 없어야 합니다.no-preference의 모션은 그대로 유지하세요. - 터치에는 호버가 없습니다. 터치 디바이스에서 모든 호버 기반 애니메이션을 제거하세요. 예를 들어, 데스크톱에서 마우스를 올리면 카드가 10px 위로 올라가는 경우, 터치에서는
@media (hover: hover)안에 넣으세요. - 글꼴 로딩 상태:
font-display: swap. 레이아웃 시프트를 방지하기 위해 폴백 글꼴에 대해 동일한line-height와letter-spacing을 설정하세요.font-display: optional은 표시 시간을 단축하므로, 이로 인해 방문자가 FOUT(Flash of Unstyled Text)을 볼 위험이 있습니다.font-display: swap은 브랜드 일관성을 유지하기 위해 더 안전합니다. - 무한 루프에는 특별한 처리가 필요합니다. 끝없는 루프(예: 카드 회전)는 영원히 같은 속도와 같은 모션으로 실행되어야 합니다.
alternate나reverse가 필요할 수 있습니다.
모션 검토 체크리스트 (Motion review checklist)
프로젝트에서 모든 모션을 확인할 때 이 체크리스트를 실행하세요. 이 체크리스트를 실행하기 전에 느낌이 올바른지 확인하세요.
- 느낌이 적용되었나요? 하나의 느낌이 모든 요소에 적용되었습니까?
- 속도가 일관되나요? 모든 요소가 일관된 속도를 사용합니까?
- 거리가 일관되나요? 텍스트와 이미지의 거리가 일치합니까?
- 스태거가 일관되나요? 스태거가 모든 요소에 대해 일관된 값을 사용합니까?
- 지연이 올바른가요? 지연이 다른 애니메이션 완료와 일치합니까?
- 시퀀스가 올바른가요? 요소가 올바른 순서로 나타납니까? (계층 구조대로)
- 이징이 올바른가요? 이징이 느낌과 일치합니까?
- 오버슈트가 올바른가요? 오버슈트가 의도한 대로입니까?
- 원점이 올바른가요? 요소가 올바른 방향에서 커지거나 축소됩니까?
- 가시성: 이 모션이 항상 표시되나요, 아니면 (
overflow: hidden에 의해) 잘리는 부분이 있나요? - 성능: 모션이 60fps를 유지하나요? DevTools 성능 탭에서 확인하세요. 레이아웃이나 페인트 트리거를 찾고,
transform과opacity만 사용하도록 변경하세요.
참고 자료 (References)
references/feels.md: 각 느낌에 대한 자세한 값, 바로 붙여넣을 수 있는 코드 및 효과assets/feels-demo.html: 느낌을 비교할 수 있는 대화형 데모 페이지