CSS의 색상 애니메이션: 전환 및 키프레임
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
컬러 애니메이션은 웹 디자이너가 사용할 수 있는 가장 표현력이 뛰어난 도구 중 하나입니다. 마우스를 올리면 색상을 바꾸는 버튼, 새벽과 황혼에 그라데이션을 순환하는 배경, 에너지로 색상이 펄스되는 로딩 표시기 등 이러한 효과는 JavaScript 한 줄 없이도 분위기를 설정하고 상태를 전달하며 인터페이스에 생명을 추가합니다. 그러나 CSS 색상 애니메이션에는 숙련된 개발자조차 당황하게 만드는 미묘한 차이가 있습니다. 애니메이션 속성, 브라우저가 색상 사이를 보간하는 방법, 일부 전환이 중간에 흐릿하게 보이는 이유, 최신 색상 공간을 사용하여 매끄럽고 지각적으로 자연스러운 결과를 얻는 방법 등이 있습니다.
이 가이드에서는 CSS 색상 전환, 키프레임 애니메이션, HSL 기반 색조 회전, 인지적 부드러움을 위한 OKLCH 보간, 모든 장치에서 애니메이션을 원활하게 유지하는 성능 고려 사항을 다룹니다.
CSS 색상 전환
transition 속성은 CSS 속성이 변경될 때마다 한 값에서 다른 값으로 원활하게 애니메이션을 적용하도록 브라우저에 지시합니다. 색상 속성(color, background-color, border-color, outline-color, fill, stroke 등)은 모두 애니메이션 가능합니다.
기본 구문
.button {
background-color: #3B82F6;
transition: background-color 200ms ease;
}
.button:hover {
background-color: #1D4ED8;
}
커서가 버튼에 들어가면 브라우저는 200밀리초에 걸쳐 #3B82F6(Tailwind blue-500)에서 #1D4ED8(Tailwind blue-700)까지 애니메이션을 적용합니다. 커서가 떠나면 다시 애니메이션됩니다.
transition 약칭은 property duration easing-function delay를 허용합니다. 여러 전환을 쉼표로 구분할 수 있습니다.
.card {
background-color: #F8FAFC;
border-color: #E2E8F0;
transition:
background-color 300ms ease,
border-color 300ms ease;
}
.card:hover {
background-color: #EFF6FF;
border-color: #BFDBFE;
}
전환 타이밍 기능
감속/가속 기능은 애니메이션 중 변화 속도를 제어합니다.
| 키워드 | 행동 |
|---|---|
ease |
느린 시작, 빠른 중간, 느린 끝(기본값) |
ease-in |
느린 시작, 빠른 마무리 |
ease-out |
빠른 시작, 느린 완료 |
ease-in-out |
느린 시작과 끝, 빠른 중간 |
linear |
전체적으로 일정한 비율 |
cubic-bezier(x1, y1, x2, y2) |
사용자 정의 곡선 |
색상 전환의 경우 ease-out가 가장 자연스러운 느낌을 주는 경우가 많습니다. 즉, 색상이 대략적인 목표에 빠르게 도달한 다음 안정되어 물리적인 색상 인식이 작동하는 방식과 일치합니다.
color 및 다중 속성 전환
all를 사용하여 애니메이션 가능한 모든 속성을 전환할 수 있지만 다른 속성이 동시에 변경되면 의도하지 않은 부작용이 발생할 수 있습니다. 명시적으로 표현하는 것이 더 좋습니다.
.link {
color: #6366F1;
text-decoration-color: transparent;
transition:
color 150ms ease-out,
text-decoration-color 150ms ease-out;
}
.link:hover {
color: #4338CA;
text-decoration-color: #4338CA;
}
키프레임 색상 애니메이션
@keyframes 규칙은 연속적으로 재생되거나 설정된 횟수만큼 반복되거나 트리거에서 실행될 수 있는 명명된 애니메이션 시퀀스를 정의합니다. 전환과 달리 키프레임은 상태 변경 없이 작동합니다. 페이지 로드 시 자동으로 실행되거나 무기한 반복될 수 있습니다.
기본 키프레임 구문
@keyframes pulse-blue {
0% { background-color: #3B82F6; }
50% { background-color: #60A5FA; }
100% { background-color: #3B82F6; }
}
.status-indicator {
animation: pulse-blue 2s ease-in-out infinite;
}
이는 #3B82F6(파란색-500)과 #60A5FA(파란색-400) 사이를 진동하는 펄스 상태 표시기를 생성하여 미묘한 호흡 효과를 제공합니다.
키프레임의 여러 색상 중단점
@keyframes sunrise {
0% { background-color: #0F172A; } /* Deep night */
25% { background-color: #7C3AED; } /* Pre-dawn violet */
50% { background-color: #F97316; } /* Dawn orange */
75% { background-color: #FDE68A; } /* Morning yellow */
100% { background-color: #BFDBFE; } /* Clear sky blue */
}
.hero-background {
animation: sunrise 8s ease-in-out forwards;
}
색상은 #0F172A → #7C3AED → #F97316 → #FDE68A → #BFDBFE를 거쳐 영화 같은 시간 효과를 만들어냅니다.
애니메이션 속성
animation 약칭은 다음을 허용합니다.
name duration timing-function delay iteration-count direction fill-mode play-state
.element {
/* Name | Duration | Easing | Delay | Iterations | Direction */
animation: pulse-blue 2s ease-in-out 0s infinite alternate;
}
alternate 방향은 애니메이션이 앞으로 재생된 다음 뒤로 재생되도록 하여 마지막에 급격하게 점프하지 않고 부드러운 루프를 생성합니다. 이는 컬러 펄스 효과에 이상적입니다.
부드러운 색조 회전을 위한 HSL 기반 애니메이션
HSL(색조, 채도, 밝기)은 색상이 색상환 주위의 단일 숫자 값(도 단위)이기 때문에 색상 회전을 간단하게 만듭니다. 스펙트럼의 모든 색상을 통해 색조 0부터 색조 360까지 애니메이션을 적용합니다.
HSL 애니메이션을 위한 CSS 사용자 정의 속성
가장 우아한 접근 방식은 @keyframes와 결합된 CSS 사용자 정의 속성을 사용합니다.
:root {
--hue: 220;
}
.rainbow-button {
background-color: hsl(var(--hue) 70% 55%);
transition: background-color 100ms linear;
}
@keyframes hue-rotate {
from { --hue: 0; }
to { --hue: 360; }
}
.rainbow-button {
animation: hue-rotate 4s linear infinite;
}
그러나 문제가 있습니다. 브라우저가 속성 유형을 모르기 때문에 CSS는 기본적으로 사용자 정의 속성 값 사이를 보간할 수 없습니다. 이것이 @property가 들어오는 곳입니다.
애니메이션 사용자 정의 속성에 대한 @property 규칙
@property는 특정 유형의 사용자 정의 속성을 등록하여 브라우저가 이를 원활하게 보간할 수 있도록 합니다.
@property --hue {
syntax: "<number>";
initial-value: 0;
inherits: false;
}
@keyframes hue-rotate {
from { --hue: 0; }
to { --hue: 360; }
}
.rainbow-text {
color: hsl(var(--hue) 80% 45%);
animation: hue-rotate 6s linear infinite;
}
--hue를 <number>로 선언하는 @property를 사용하면 브라우저는 전체 색조 휠을 순환하면서 0에서 360 사이를 부드럽게 보간합니다.
테마 효과를 위한 부분 색조 회전
흥미로운 효과를 만들기 위해 완전한 360도 회전이 필요하지 않습니다. 더 좁은 색조 범위 내에서 애니메이션을 적용하면 더욱 절제된 브랜드 느낌을 연출할 수 있습니다.
@property --hue {
syntax: "<number>";
initial-value: 210;
inherits: false;
}
@keyframes ocean-shift {
0% { --hue: 195; } /* Cyan */
50% { --hue: 230; } /* Blue */
100% { --hue: 195; } /* Back to cyan */
}
.ocean-card {
background-color: hsl(var(--hue) 60% 45%);
animation: ocean-shift 5s ease-in-out infinite;
}
이는 청록색#00BFCE와 유사과 중간 파란색#4166CC와 유사 사이를 이동하여 청청색 계열을 벗어나지 않고도 유동적인 해조 효과를 생성합니다.
밝기 및 채도 애니메이션
색조 외에도 채도와 밝기에 애니메이션을 적용하여 펄스, 페이딩 또는 활력 효과를 만들 수 있습니다.
@property --lightness {
syntax: "<percentage>";
initial-value: 55%;
inherits: false;
}
@keyframes pulse-light {
0%, 100% { --lightness: 45%; }
50% { --lightness: 65%; }
}
.pulse {
background-color: hsl(220 70% var(--lightness));
animation: pulse-light 2s ease-in-out infinite;
}
이는 파란색 색조의 부드러운 밝기 펄스를 생성하여 알림 배지나 주의를 끄는 요소에 이상적입니다.
지각적 부드러움을 위한 OKLCH 보간
HSL 기반 애니메이션은 편리하지만 잘 알려진 문제가 있습니다. 특정 색상 사이의 전환 중간점이 시각적으로 불쾌해 보입니다. 흐릿하고 채도가 낮은 회색 영역을 통과하거나 디자이너가 의도하지 않은 중간 색상을 통과합니다.
이는 HSL과 sRGB가 지각적으로 균일하지 않기 때문에 발생합니다. 동일한 숫자 단계는 동일한 인식 단계를 생성하지 않습니다. 두 HSL 색상 사이의 보간 경로는 인식상 끝점 사이의 중간에 있지 않은 중간 색상을 통과합니다.
OKLCH(OK Lightness-Chroma-Hue)는 이 문제를 해결합니다. 동일한 숫자 단계가 동일한 인식 단계를 생성하도록 설계되었습니다. OKLCH 색상 간의 전환은 예상치 못한 회색 영역이나 색조 변화 없이 부드럽고 생생한 중간점을 생성합니다.
OKLCH로 애니메이션 만들기
@property --oklch-hue {
syntax: "<number>";
initial-value: 270;
inherits: false;
}
@keyframes perceptual-hue-rotate {
from { --oklch-hue: 0; }
to { --oklch-hue: 360; }
}
.smooth-rainbow {
color: oklch(60% 0.18 var(--oklch-hue));
animation: perceptual-hue-rotate 8s linear infinite;
}
hsl()를 사용한 동일한 애니메이션과 비교하여 OKLCH 버전은 회전 전반에 걸쳐 일관된 인식 밝기를 유지합니다. 색상은 HSL 휠의 노란색, 청록색 또는 기타 지각적으로 균일하지 않은 영역을 통과할 때 어둡거나 창백한 영역으로 떨어지지 않습니다.
직접 OKLCH 전환
OKLCH 보간은 두 가지 특정 색상 사이의 transition에 특히 강력합니다.
.button {
/* From: vibrant purple [#7C3AED equivalent] */
background-color: oklch(50% 0.22 285deg);
transition: background-color 400ms ease;
}
.button:hover {
/* To: vivid blue [#2563EB equivalent] */
background-color: oklch(50% 0.22 255deg);
}
두 색상 모두 동일한 OKLCH 밝기(50%)와 채도(0.22)를 갖기 때문에 두 색상 사이의 전환은 전체적으로 일정한 인식 밝기와 채도를 유지하며 색상만 변경됩니다. sRGB 또는 HSL에서 등가 전환은 중간에서 눈에 띄게 밝아지거나 어두워집니다.
ColorFYI의 색상 변환기를 사용하여 16진수 브랜드 색상에 해당하는 OKLCH를 찾은 다음 가장 부드러운 결과를 위해 애니메이션 정의에 해당 값을 사용합니다.
OKLCH 보간법을 사용한 CSS 그라디언트
OKLCH는 또한 그라디언트 품질을 향상시킵니다. CSS Color 4를 사용하면 그라디언트의 보간 색상 공간을 지정할 수 있습니다.
/* Standard sRGB interpolation — may show gray muddy zone in the middle */
background: linear-gradient(to right, #FF0000, #0000FF);
/* OKLCH interpolation — smooth, perceptually uniform */
background: linear-gradient(in oklch to right, oklch(60% 0.25 27deg), oklch(60% 0.25 265deg));
in oklch 키워드는 OKLCH 공간에서 그래디언트를 보간하도록 브라우저에 지시합니다. 이렇게 하면 중간점을 통해 인지된 밝기가 일정하게 유지되고 더 풍부한 중간 색상이 생성됩니다.
이 기술을 ColorFYI의 Gradient Generator와 결합하여 시각적으로 기본 그라데이션을 구축한 다음 지각적 균일성을 위해 in oklch를 추가합니다.
OKLCH의 색조 보간 방향
유용한 OKLCH 관련 옵션은 보간이 이동하는 색상환 주위 방향을 제어하는 것입니다.
/* Shorter arc (default) — may skip through unintended hues */
background: linear-gradient(in oklch to right,
oklch(55% 0.2 60deg), /* Yellow-orange */
oklch(55% 0.2 300deg) /* Magenta */
);
/* Longer arc — explicitly travels through blue-green region */
background: linear-gradient(in oklch longer hue to right,
oklch(55% 0.2 60deg),
oklch(55% 0.2 300deg)
);
shorter hue(기본값)는 항상 색상환 주위의 더 짧은 경로를 사용합니다. longer hue는 더 긴 경로를 사용합니다. 이를 통해 그라디언트나 애니메이션에 나타나는 중간 색상을 제어할 수 있습니다.
성능 고려 사항
컬러 애니메이션에는 브라우저의 렌더링 파이프라인이 포함됩니다. 성능 문제가 발생하는 위치를 이해하면 중급형 모바일 장치에서도 원활하게 유지되는 애니메이션을 디자인하는 데 도움이 됩니다.
애니메이션의 안전한 속성
CSS 애니메이션은 렌더링 파이프라인의 다양한 단계를 트리거합니다. 성능의 목표는 GPU에서 처리하는 합성 단계를 유지하고 레이아웃 또는 페인트를 트리거하지 않는 것입니다.
| 부동산 | 파이프라인 단계 | 성과 |
|---|---|---|
transform, opacity |
합성기 | 우수 |
background-color, color, border-color |
페인트 | 좋음 - 가끔씩 다시 칠함 |
width, height, margin, padding |
레이아웃 + 페인트 | 비용이 많이 들므로 애니메이션을 사용하지 마세요 |
색상 애니메이션(background-color, color)은 각 프레임에서 다시 그리기를 트리거합니다. 브라우저는 영향을 받는 요소의 픽셀 색상을 다시 계산해야 합니다. 이는 일반적으로 최신 장치에서 빠르고 GPU 가속이지만 transform 및 opacity 애니메이션만큼 무료는 아닙니다.
리페인트 영역 최소화
재도색 비용은 재도색되는 면적에 비례합니다. 전체 화면 히어로 섹션의 배경색 애니메이션은 작은 상태 표시기 애니메이션보다 훨씬 더 많은 픽셀을 다시 그립니다. 넓은 영역의 컬러 애니메이션의 경우 다음을 고려하십시오.
의사 요소 오버레이 사용: 정적 배경 위에 컬러 의사 요소의 opacity를 애니메이션화합니다. opacity는 합성기 전용이며 다시 그리기를 트리거하지 않습니다.
.hero {
position: relative;
background-color: #1E3A8A;
}
.hero::after {
content: "";
position: absolute;
inset: 0;
background-color: #7C3AED;
opacity: 0;
transition: opacity 600ms ease;
}
.hero:hover::after {
opacity: 1;
}
이는 컴포지터 수준 작업만 사용하여 색상 오버레이를 페이드 인하여 "색상 변경" 효과를 얻습니다.
그라데이션 애니메이션 제한사항
표준 CSS는 두 개의 서로 다른 background-image 그래디언트 값 사이를 보간할 수 없습니다. 두 linear-gradient() 값 사이를 전환하려고 하면 브라우저가 부드럽게 애니메이션을 적용하지 않고 두 값 사이를 스냅합니다.
/* This will NOT animate smoothly */
.element {
background: linear-gradient(45deg, #3B82F6, #8B5CF6);
transition: background 500ms ease; /* Snaps, does not animate */
}
.element:hover {
background: linear-gradient(45deg, #EF4444, #F97316);
}
솔루션:
옵션 1: 대형 그라디언트에서 background-position 애니메이션
.element {
background: linear-gradient(45deg, #3B82F6, #8B5CF6, #EF4444, #F97316);
background-size: 300% 300%;
background-position: 0% 50%;
transition: background-position 800ms ease;
}
.element:hover {
background-position: 100% 50%;
}
옵션 2: @property를 통해 그라데이션 색상 정지 애니메이션
@property --color-start {
syntax: "<color>";
initial-value: #3B82F6;
inherits: false;
}
@property --color-end {
syntax: "<color>";
initial-value: #8B5CF6;
inherits: false;
}
.element {
background: linear-gradient(45deg, var(--color-start), var(--color-end));
transition: --color-start 500ms ease, --color-end 500ms ease;
}
.element:hover {
--color-start: #EF4444;
--color-end: #F97316;
}
@property가 사용자 정의 속성을 <color> 유형으로 선언하면 브라우저는 색상 값 사이를 보간할 수 있으며 그라데이션이 원활하게 애니메이션됩니다.
변경 예정 및 GPU 힌트
지속적인 색상 애니메이션(항상 깜박이는 표시기, 애니메이션 배경)이 있는 요소의 경우 브라우저에 GPU 리소스를 할당하라는 힌트를 줍니다.
.always-animating {
will-change: background-color;
}
will-change를 아껴서 사용하십시오. 많은 요소에 동시에 적용하면 상당한 GPU 메모리가 소모됩니다. 실제로 지속적으로 애니메이션이 적용되는 요소용으로 예약하세요.
prefers-reduced-motion를 존중하세요
운영 체제 접근성 설정에서 동작 감소를 요청한 사용자에게는 항상 애니메이션이 아닌 대체를 제공하세요. 지속적인 애니메이션은 일부 사용자에게 메스꺼움과 전정 불편을 유발할 수 있습니다.
@keyframes hue-rotate {
from { --hue: 0; }
to { --hue: 360; }
}
.animated-element {
animation: hue-rotate 4s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.animated-element {
animation: none;
/* Optionally set a specific static color */
background-color: hsl(220 70% 55%);
}
}
이는 단순한 모범 사례가 아닙니다. 이는 WCAG 2.3 AA 적합성(성공 기준 2.3.3 상호 작용의 애니메이션)에 필요합니다.
주요 내용
- CSS 색상 전환은
transition속성을 사용하여 마우스 오버, 포커스 또는 클래스 변경 시 색상 상태 간에 애니메이션을 적용합니다.background-color,color,border-color등 모든 색상 속성은 애니메이션 가능합니다. @keyframes는 각 단계의 이징 및 타이밍을 완벽하게 제어하여 지속적으로 반복되거나, 로드 시 실행되거나, 트리거에 응답하는 다단계 컬러 애니메이션을 지원합니다.- HSL 기반 색조 회전은 스펙트럼 애니메이션에 편리합니다. 전체 색상환의 0~360주기에서 색조 정도에 애니메이션을 적용합니다.
@property를 사용하여 사용자 정의 속성을 입력된 값으로 선언하면 브라우저가 이를 원활하게 보간할 수 있습니다. - OKLCH는 HSL 또는 sRGB보다 인지적으로 더 부드러운 색상 전환을 생성합니다. 동일한 OKLCH 단계는 동일한 인지 단계를 생성하기 때문입니다. 흐릿한 회색 중간점이나 의도하지 않은 색상 변화가 없습니다. 색상 변환기를 사용하여 브랜드 색상에 대한 OKLCH 값을 찾으세요.
- 전체적으로 일관된 밝기로 인지적으로 균일한 그라데이션 보간을 얻으려면 그라데이션 선언(
linear-gradient(in oklch ...))에서in oklch를 사용합니다. - CSS는 기본적으로 두 개의 서로 다른
linear-gradient()값 사이를 보간할 수 없습니다. 해결 방법으로<color>유형 사용자 정의 속성과 함께@property를 사용하거나 대형 그라데이션에서background-position에 애니메이션을 적용하세요. - 컬러 애니메이션은 레이아웃 변경이 아닌 다시 그리기를 트리거합니다. 일반적으로 빠르지만 불투명도 기반 오버레이 기술이나 컴포지터 전용 대안을 사용하여 큰 표면 애니메이션의 다시 칠하기 영역을 최소화합니다.
- 전정 장애 또는 동작 민감도 장애가 있는 사용자를 위해 연속 애니메이션을 비활성화하려면 항상
@media (prefers-reduced-motion: reduce)재정의를 포함하세요. - ColorFYI의 Gradient Generator를 사용하여 시각적으로 애니메이션 그라데이션 색상 정지점을 만든 다음
in oklch보간법으로 다듬어 화면에서 가장 부드러운 결과를 얻습니다.