웹 애니메이션을 만들 때, 시간대나 사용자 상호작용에 따라 색상 테마를 바꾸고 싶은 경우가 많죠. 기존에는 각 색상을 일일이 하드코딩하거나 복잡한 SCSS 함수를 사용해야 했습니다. 하지만 CSS 상대 색상(Relative Color)과 OKLCH 색상 공간을 활용하면 단 하나의 기본색(--foundation)으로 전체 색상 팔레트를 시스템적으로 생성할 수 있습니다. 이 글에서는 이 강력한 기술을 실전 SVG 애니메이션에 적용하는 구체적인 방법을 알아봅니다. 자세한 근거자료는 Smashing Magazine의 원문에서 확인할 수 있어요.

핵심 개념: 상대 색상과 OKLCH
CSS 상대 색상 문법은 oklch(from [기본색] [조정값]) 형태로 사용합니다. OKLCH 색상 공간은 Lightness(명도), Chroma(채도), Hue(색상) 세 가지 채널로 구성되어 있어 색상을 직관적으로 조정하기에 좋습니다.
/* 1. 기본색 정의 (어떤 색상 형식이든 OK) */
--foundation: #5accd6;
/* 2. 상대 색상으로 파생색 생성하기 */
/* 명도 조정 (더 어둡게) */
--foundation-dark: oklch(from var(--foundation) calc(l - 0.20) c h);
/* 채도 조정 (비율로 줄이기) */
--foundation-muted: oklch(from var(--foundation) l calc(c * 0.5) h);
/* 색상 조정 (보색 만들기 - 180도 회전) */
--foundation-complement: oklch(from var(--foundation) l c calc(h + 180));
위 코드에서 l, c, h는 기본색의 명도, 채도, 색상값을 가리킵니다. calc()를 사용해 이 값들을 조정하면 새로운 색상을 만들어낼 수 있죠.

실전 적용: 애니메이션 테마 시스템 구축
색상 관계 정의 원칙
저자는 실무에서 이렇게 정리했습니다:
- 명도(Lightness)는 더하거나 빼라(Move It): 절대값 변경이 자연스럽습니다.
- 채도(Chroma)는 비율로 곱하라(Scale It): 기본색 대비 채도 비율을 유지해야 합니다.
- 색상(Hue)은 회전시켜라(Rotate It): 각도(degree)를 더하거나 빼서 조정합니다.
SVG 그래디언트에 적용하기
/* SVG 내부 스타일 */
<linearGradient id="bgGradient">
<stop offset="0%" style="stop-color: var(--grad-start);" />
<stop offset="100%" style="stop-color: var(--grad-end);" />
</linearGradient>
/* CSS에서 그래디언트 색상 정의 */
--foundation: #5accd6;
--grad-end: var(--foundation);
--grad-start: oklch(from var(--foundation)
calc(l - 0.2357) /* 명도 감소 */
calc(c * 0.833) /* 채도 비율 조정 */
h); /* 색상 유지 */
이제 --foundation 값만 바꾸면 그래디언트 시작색과 끝색이 자동으로 조정됩니다. 수동 계산은 이제 그만!

고급 기법: 색상 애니메이션까지
정적 색상 변경을 넘어, 기본색 자체를 애니메이션할 수도 있습니다. @property 규칙으로 타입을 등록하면 부드러운 보간이 가능해집니다.
/* 1. OKLCH 채널을 개별 CSS 변수로 등록 */
@property --f-l { syntax: '<number>'; inherits: true; initial-value: 0.40; }
@property --f-c { syntax: '<number>'; inherits: true; initial-value: 0.11; }
@property --f-h { syntax: '<number>'; inherits: true; initial-value: 305; }
/* 2. 등록된 변수로 기본색 재구성 */
--foundation: oklch(var(--f-l) var(--f-c) var(--f-h));
/* 3. 키프레임으로 채널 애니메이션 정의 */
@keyframes breathe {
0%, 100% { --f-l: 0.36; }
50% { --f-l: 0.46; }
}
/* 4. 애니메이션 적용 */
.toon-title {
animation: breathe 10s ease-in-out infinite;
}
--foundation이 움직이면, 이에서 파생된 모든 색상(--foundation-dark, --grad-start 등)이 함께 살아 숨쉬는 애니메이션이 완성됩니다. 하나의 값만 조절해도 전체 색상 시스템이 반응하니 유지보수도 훨씬 쉬워지겠죠?
CSS 상대 색상은 단순한 문법이 아닌, 디자인 시스템을 구축하는 강력한 패러다임입니다. 버튼 상태, 다크모드, 시각적 피드백 등 다양한 인터페이스 요소에 응용해 보세요. 색상에 대한 생각을 완전히 바꿔줄 겁니다.