튜토리얼

CSS의 색상 보간: OKLCH가 승리하는 이유

6분 읽기

CSS는 그라디언트, color-mix() 또는 전환에서 두 가지 색상을 혼합할 때마다 색상 보간을 수행합니다. 즉, 시작 색상과 끝 색상 사이의 중간 값을 계산합니다. 대부분의 웹 역사에서 해당 계산은 sRGB 색상 공간에서 이루어졌으며 결과는 종종 흐릿하거나 채도가 낮거나 지각적으로 고르지 않았습니다. 최신 CSS를 사용하면 이제 보간할 색상 공간을 선택할 수 있습니다. 선택은 매우 중요하며 OKLCH는 지속적으로 최고의 결과를 만들어냅니다.

이 튜토리얼에서는 RGB 보간이 실패하는 이유, HSL이 부족한 이유, OKLCH가 2024년 이후의 그라데이션 및 색상 혼합에 적합한 기본값인 이유를 설명합니다.

RGB 보간 문제: 중간점이 흐려짐

색상 공간을 지정하지 않고 CSS 그라데이션을 작성하면 브라우저는 sRGB로 보간합니다. 즉, R, G, B 채널 값을 독립적으로 선형 혼합하여 중간 색상을 계산합니다.

이는 타당해 보이지만 두 끝점이 sRGB 큐브의 중앙을 통과하면 심각하게 무너집니다. 빨간색에서 녹색으로의 그라데이션을 고려해보세요.

/* Default: interpolates in sRGB */
background: linear-gradient(to right, #FF0000, #00FF00);

sRGB에서 이 그라데이션의 중간점은 #808000입니다. 즉, 흐릿한 올리브색입니다. 수학적으로 RGB 128, 128, 0은 채널 값에서 빨간색과 녹색의 정확히 중간에 있습니다. 그러나 지각상으로는 두 개의 생생한 원색 사이의 생생한 중간점처럼 보이지 않습니다. 그라데이션은 진흙 투성이의 어두운 계곡을 통과하여 처지고 반대쪽은 밝아집니다.

근본적인 문제는 sRGB가 지각적으로 균일하지 않다는 것입니다. R, G, B의 동일한 수치 단계는 인지된 색상이나 밝기의 동일한 단계에 해당하지 않습니다. sRGB 큐브는 인간의 시각이 아닌 디스플레이 하드웨어용으로 설계되었습니다.

/* You can force sRGB explicitly */
background: linear-gradient(in srgb, red, blue);

/* Or use the legacy syntax (same result) */
background: linear-gradient(red, blue);

둘 다 동일한 채도가 낮은 중간점을 생성합니다. 문제는 구문이 아니라 색상 공간 자체입니다.

감마 문제

또 다른 미묘함이 있습니다: sRGB 값은 감마 인코딩됩니다. 원시 sRGB 값 0.5는 디스플레이에서 방출되는 물리적 빛의 50%에 해당하지 않습니다. 그라데이션의 실제 지각 중간점은 감마 인코딩된 sRGB가 아닌 선형 조명에서 계산되어야 합니다. CSS 레벨 4에서는 이 문제를 해결하기 위해 in srgb-linear를 도입했습니다.

background: linear-gradient(in srgb-linear, red, blue);

선형 sRGB는 휘도 전환에 있어 감마 sRGB보다 우수하지만 여전히 직사각형 RGB 공간이기 때문에 색상 변화 및 채도 저하 문제를 해결하지 못합니다.

HSL 색조 변화

HSL은 RGB보다 사람이 더 읽기 쉬운 대안으로 도입되었습니다. 원통형 표현(0~360 각도의 색조, 백분율로 표시된 채도 및 밝기)을 통해 색상 관계를 더 쉽게 추론할 수 있습니다. 그러나 HSL 보간에는 색조 변화라는 고유한 실패 모드가 있습니다.

두 HSL 색상 사이를 보간하면 브라우저는 색상 원의 가장 짧은 호를 따라 이동합니다. 따뜻한 빨간색(hsl(10, 100%, 50%))에서 시원한 파란색(hsl(220, 100%, 50%))으로 이동하면 최단 경로는 보라색과 보라색을 통과합니다. 이는 원하는 것일 수도 있고 아닐 수도 있습니다.

그러나 더 깊은 문제는 HSL의 가벼움이 지각적으로 균일하지 않다는 것입니다. hsl(60, 100%, 50%)의 노란색은 동일한 L 값을 공유하더라도 hsl(240, 100%, 50%)의 파란색보다 훨씬 더 밝게 보입니다. HSL에서 노란색에서 파란색으로 보간하면 인식된 밝기가 일관되지 않은 방식으로 흔들리고 처집니다.

/* HSL gradient — perceptual brightness is uneven across hues */
background: linear-gradient(in hsl, hsl(60 100% 50%), hsl(240 100% 50%));

hsl(150, 100%, 50%)에서 이 그라데이션의 중간점은 두 끝점보다 인지적으로 더 밝게 나타나는 선명한 녹색입니다. 그라데이션이 부드럽게 전환되지 않고 중간에서 최고점에 도달합니다.

HSL 보간에는 장호 문제도 있습니다. 색상 각도는 360°로 순환하며, hsl(350, ...)(빨간색에 가까움)에서 hsl(20, ...)(주황색)로 보간하면 HSL은 빨간색을 통과하는 단거리가 아닌 파란색, 녹색, 노란색을 통해 색상 원 주위로 먼 길을 이동할 수 있습니다.

OKLCH: 일관성과 지각적 통일성

OKLCH는 Oklab 색상 공간의 원통형 형태로, Björn Ottosson이 2020년에 이전 색상 공간의 지각 균일성 단점을 해결하기 위해 특별히 설계했습니다. L(밝기), C(색도) 및 H(색조 각도)의 세 가지 채널은 L의 동일한 수치 변화가 색상에 관계없이 인지된 밝기의 동일한 변화를 생성하도록 보정됩니다.

두 OKLCH 색상 사이를 보간하면 다음과 같은 결과를 얻을 수 있습니다.

  1. 전환 전반에 걸쳐 일관되게 인지된 밝기 - 어두운 중간점으로 처지거나 밝은 정점이 흔들리는 일이 없습니다.
  2. 채도 보존 - 채도가 색조와 독립적으로 보간되므로 중간점이 생생하게 유지됩니다.
  3. 더 짧고 더 직관적인 색상 경로 — OKLCH의 색상 각도는 인지 순서에 따라 분포되므로 보간은 예상되는 중간 색상을 통해 이동합니다.
/* OKLCH gradient — vivid, perceptually even */
background: linear-gradient(in oklch, red, blue);

OKLCH의 빨간색에서 파란색으로의 그라데이션은 지각적으로 직관적인 중간점인 선명한 자홍색과 보라색을 통해 이동합니다. 전체적으로 채도가 높고 균일한 밝기를 유지합니다.

나란히 비교

그라데이션 중간점 색상 인지된 품질
빨간색에서 녹색으로 in srgb #808000 — 둔한 올리브 진흙탕, 어두운 계곡
노란색에서 파란색으로 in hsl 선명한 녹색 피크 고르지 못한 밝기, 색상 스파이크
빨간색에서 녹색으로 in oklch 생생한 따뜻한 노란색 부드럽고, 포화되고, 심지어

차이점을 직접 확인하려면 다양한 색상 공간에 걸쳐 그라디언트를 미리 볼 수 있는 그라디언트 생성기를 사용하세요.

색상을 OKLCH로 변환하는 방법

CSS의 모든 색상 값을 다시 작성할 필요는 없습니다. 그라데이션의 in oklch 플래그는 보간하기 전에 끝점 색상을 OKLCH로 변환한 다음 다시 출력 색상 공간으로 변환하도록 브라우저에 지시합니다. HEX 값을 유지할 수 있습니다.

/* These HEX endpoints are automatically converted to OKLCH for interpolation */
background: linear-gradient(in oklch, #FF5733, #3498DB);

#FF5733는 대략 oklch(0.63 0.24 27)이고 #3498DB는 대략 oklch(0.63 0.14 232)입니다. 그라디언트를 디자인하기 전에 색상 변환기를 사용하여 HEX 코드의 OKLCH 값을 확인하면 보간이 무엇을 통과할지 미리 알 수 있습니다.

color-mix() 기능

CSS color-mix()는 두 가지 색상을 혼합하기 위한 선언적 API로, 2023년 이후 모든 최신 브라우저에서 사용할 수 있습니다. 해당 구문에는 보간 색상 공간이 첫 번째 인수로 포함됩니다.

color: color-mix(in oklch, #FF5733 50%, #3498DB);

이는 OKLCH 공간에서 #FF5733#3498DB를 동일한 비율로 혼합합니다. 그 결과 흐릿한 sRGB 평균이 아닌 두 색상 사이의 실제 지각 중간점처럼 보이는 생생한 중간 색상이 생성됩니다.

color-mix()의 실용적인 용도

투명 변형 만들기:

:root {
  --brand: #2563EB;
  --brand-10: color-mix(in oklch, var(--brand) 10%, transparent);
  --brand-20: color-mix(in oklch, var(--brand) 20%, transparent);
  --brand-50: color-mix(in oklch, var(--brand) 50%, transparent);
}

흰색이나 검정색 쪽으로 착색됨:

:root {
  --brand: #2563EB;
  --brand-light: color-mix(in oklch, var(--brand) 70%, white);
  --brand-dark:  color-mix(in oklch, var(--brand) 70%, black);
}

이는 셰이드 생성기와 동일한 아이디어이지만 전처리 없이 완전히 CSS로 구현됩니다. OKLCH 색조의 결과는 HSL의 동등한 작업보다 더 자연스럽게 보입니다. 흰색이나 검정색에 가까워짐에 따라 채도가 적절하게 이동하기 때문입니다.

호버 상태 파생:

.button {
  background: var(--brand);
}
.button:hover {
  background: color-mix(in oklch, var(--brand) 80%, black);
}

경고: sRGB color-mix()

in <colorspace> 인수를 생략하면 color-mix()는 기본적으로 sRGB 보간으로 설정됩니다.

/* This uses sRGB — may produce muddy results */
color: color-mix(#FF5733, #3498DB);

/* Correct: specify the space */
color: color-mix(in oklch, #FF5733, #3498DB);

항상 in oklch(또는 다른 기본 공간)를 명시적으로 지정하세요. 기본 sRGB는 이전 버전과의 호환성을 위해 유지되지만 최선의 선택은 아닙니다.

그라데이션 보간 색 공간

최신 CSS 구문을 사용하면 방향 키워드 뒤에 in <colorspace>를 사용하여 그라데이션 선언에서 보간 색상 공간을 직접 지정할 수 있습니다.

/* sRGB (default, often muddy) */
background: linear-gradient(to right, red, blue);

/* Linear sRGB (better luminance, still has hue issues) */
background: linear-gradient(in srgb-linear to right, red, blue);

/* HSL (hue shifts, uneven brightness) */
background: linear-gradient(in hsl to right, red, blue);

/* OKLCH (recommended: vivid, perceptually uniform) */
background: linear-gradient(in oklch to right, red, blue);

/* Oklab (also excellent, less intuitive syntax) */
background: linear-gradient(in oklab to right, red, blue);

이 구문은 linear-gradient, radial-gradientconic-gradient 등 모든 그래디언트 유형에 적용됩니다.

OKLCH의 색조 보간 방향

특히 색상 보간의 경우 그라데이션이 색상 원 주위에 더 짧은 호를 사용하는지 또는 더 긴 호를 사용하는지 제어할 수 있습니다.

/* Shorter arc (default) */
background: linear-gradient(in oklch, hsl(30 100% 50%), hsl(270 100% 50%));

/* Longer arc — travels through yellow, green, cyan, then to purple */
background: linear-gradient(in oklch longer hue, hsl(30 100% 50%), hsl(270 100% 50%));

/* Increasing arc — always goes in the direction of increasing hue angle */
background: linear-gradient(in oklch increasing hue, hsl(30 100% 50%), hsl(270 100% 50%));

shorter hue 키워드(기본값)는 대부분의 경우 가장 자연스러운 결과를 제공합니다. longer hue 변형은 무지개 효과에 유용하거나 그라데이션이 색조 스펙트럼의 넓은 부분을 통과하도록 특별히 원하는 경우에 유용합니다.

다중 정지 그라디언트

OKLCH 보간은 각 세그먼트가 지각적으로 생생한 중간점을 통해 보간되기 때문에 다중 정지 그라디언트에 더욱 유용합니다.

/* A rainbow gradient that stays vivid throughout */
background: linear-gradient(
  in oklch to right,
  oklch(0.70 0.20 30),   /* orange-red */
  oklch(0.80 0.20 90),   /* yellow */
  oklch(0.75 0.20 150),  /* green */
  oklch(0.65 0.20 240),  /* blue */
  oklch(0.60 0.20 300)   /* purple */
);

L 및 C 값은 지각적으로 보정되므로 모든 스탑에서 유사한 값으로 설정하면 sRGB 무지개에서 흔히 발생하는 휘도 저하 없이 자연스럽게 밝고 채도가 높은 무지개가 생성됩니다.

브라우저 지원

in <colorspace> 그라데이션 구문은 모든 주요 브라우저에서 지원됩니다.

  • Chrome/Edge: 버전 111(2023년 3월)부터 전체 지원
  • Firefox: 버전 113부터 전체 지원(2023년 5월)
  • Safari: 버전 16.2(2022년 12월)부터 전체 지원

이전 브라우저의 경우 먼저 레거시 구문을 사용하여 적절하게 대체합니다.

/* Fallback: sRGB gradient */
background: linear-gradient(to right, #FF5733, #3498DB);

/* Modern: OKLCH interpolation */
@supports (background: linear-gradient(in oklch, red, blue)) {
  background: linear-gradient(in oklch to right, #FF5733, #3498DB);
}

주요 내용

  • sRGB 보간(CSS 기본값)은 그라데이션이 sRGB 큐브의 중심 근처를 통과할 때 흐릿하고 채도가 낮은 중간점을 생성합니다. 특히 빨간색에서 녹색 및 보색 그라데이션에서 볼 수 있습니다.
  • HSL 보간은 일부 RGB 문제를 방지하지만 인지된 밝기가 일관되지 않게 발생합니다. 밝기 채널은 인지적으로 균일하지 않으며 예상치 못한 색상 경로가 생성될 수 있습니다.
  • OKLCH 보간은 인간의 시각을 중심으로 설계되었기 때문에 생생하고 지각적으로 일관된 중간점을 생성합니다. OKLCH의 그라데이션은 전체 범위에 걸쳐 채도가 높고 균일한 밝기를 유지합니다.
  • 모든 그라데이션에서 in oklch를 사용하세요: linear-gradient(in oklch to right, red, blue). 프로그래밍 방식 블렌딩에는 color-mix(in oklch, color1 50%, color2)를 사용합니다.
  • 색상 변환기를 사용하면 HEX 또는 RGB 값을 OKLCH로 변환할 수 있으므로 그라데이션 디자인을 적용하기 전에 색상이 어떻게 보간되는지 이해할 수 있습니다.
  • 그라디언트 생성기를 사용하면 다양한 색상 공간이 색상 쌍의 그라데이션 출력에 어떤 영향을 미치는지 미리 볼 수 있습니다.
  • 색상 보간 방향은 shorter hue, longer hue, increasing huedecreasing hue 키워드로 제어할 수 있습니다. 이는 무지개 효과 및 정밀한 멀티스톱 그라데이션 제어에 유용합니다.

관련 색상

관련 브랜드

관련 도구