튜토리얼

CSS color-mix(): 브라우저에서 기본적으로 색상 혼합

7분 읽기

수년 동안 CSS에서 색상 변형을 생성하려면 모든 색상을 직접 하드코딩하거나 JavaScript 및chroma.js 또는tinycolor2와 같은 색상 조작 라이브러리를 사용해야 했습니다. CSS color-mix() 기능이 이를 변경합니다. 이는 이제 모든 주요 브라우저에서 지원되는 기본 CSS 기능으로, 두 가지 색상을 지정된 비율로 함께 혼합합니다. 즉, JavaScript나 사전 처리 없이 스타일시트에서 직접 사용할 수 있습니다.

이 기사에서는 구문 전체를 다루고, 색상 공간 선택이 모든 것을 바꾸는 이유를 설명하고, color-mix()를 실제로 유용하게 만드는 실제 사용 사례를 살펴보고, 브라우저 지원 및 대체 전략을 다룹니다.

컬러믹스()란 무엇인가요?

color-mix()는 두 가지 색상 값과 혼합 비율을 사용하여 결과 혼합 색상을 반환하는 CSS 색상 레벨 5 함수입니다. 이는 두 개의 페인트를 함께 혼합하는 CSS와 동일하지만 중요한 추가 매개변수인 혼합이 발생하는 색상 공간이 있습니다.

가장 간단한 사용 사례는 기본 색상에서 색조와 음영을 만드는 것입니다. 브랜드 파란색의 모든 색상 변형을 직접 정의하는 대신 동적으로 파생할 수 있습니다.

:root {
  --brand-blue: #2563EB;

  /* Tints — mix with white */
  --brand-blue-light:   color-mix(in oklch, var(--brand-blue) 60%, white);
  --brand-blue-lighter: color-mix(in oklch, var(--brand-blue) 30%, white);

  /* Shades — mix with black */
  --brand-blue-dark:    color-mix(in oklch, var(--brand-blue) 80%, black);
  --brand-blue-darker:  color-mix(in oklch, var(--brand-blue) 50%, black);
}

기본 파란색 #2563EB은 한 번 정의됩니다. 색조와 음영은 그것에서 파생됩니다. 브랜드 색상이 변경되면 모든 변형이 자동으로 업데이트됩니다.

구문 및 매개변수

color-mix()의 전체 구문은 다음과 같습니다.

color-mix(in <color-space>, <color1> [<percentage>]?, <color2> [<percentage>]?)

색 공간 매개변수

첫 번째 인수인 in <color-space>는 필수이며 혼합이 발생하는 위치를 지정합니다. 유효한 옵션은 다음과 같습니다.

  • srgb — 표준 RGB로 혼합됩니다(가장 친숙하지만 중간점이 흐릿한 경향이 있음).
  • hsl — HSL 실린더를 따라 블렌드
  • hwb — HWB(색조, 백색도, 흑도) 혼합
  • lab — CIE Lab에서 혼합(지각적으로 균일함)
  • oklab — Oklab에서 혼합(CIE Lab보다 균일성이 좋음)
  • lch — LCH(원통형 CIE Lab)의 혼합
  • oklch — OKLCH 혼합(원통형 Oklab, 대부분의 사용에 권장)
  • display-p3 — 디스플레이 P3 넓은 영역에 혼합
  • xyz — CIE XYZ 혼합

대부분의 디자인 작업에서 oklch는 가장 지각적으로 자연스러운 결과를 만들어냅니다. 이에 대한 자세한 내용은 다음 섹션에서 확인하세요.

색상 인수

두 가지 색상 값은 유효한 CSS 색상(16진수 코드, rgb(), hsl(), oklch(), 명명된 색상 또는 CSS 사용자 정의 속성)일 수 있습니다. 각 색상은 선택적으로 해당 색상이 혼합에 얼마나 기여하는지 나타내는 백분율을 가질 수 있습니다.

/* 50/50 mix (default when no percentages given) */
color-mix(in oklch, #FF5733, #3498DB)

/* 70% first color, 30% second */
color-mix(in oklch, #FF5733 70%, #3498DB 30%)

/* 80% first color — second color percentage is inferred as 20% */
color-mix(in oklch, #FF5733 80%, #3498DB)

백분율의 합이 100% 미만이면 결과가 부분적으로 투명해집니다. 100%를 초과하면 백분율이 정규화됩니다. 두 비율 모두 지정되지 않은 경우 혼합은 50/50입니다.

/* These are equivalent */
color-mix(in srgb, blue, red)
color-mix(in srgb, blue 50%, red 50%)
color-mix(in srgb, blue 50%, red)

다양한 색상 공간에서 혼합

색상 공간을 선택하는 것은 미용적인 것이 아닙니다. 생성되는 색상을 근본적으로 변경합니다. 같은 두 가지 색상이 서로 다른 공간에서 혼합되어도 극적으로 다른 결과가 나옵니다.

sRGB에서 혼합

sRGB 블렌딩은 빨간색, 녹색 및 파란색 채널을 선형으로 보간하는 방식으로 작동합니다. 많은 색상 쌍의 경우 이는 허용 가능한 결과를 생성하지만 보색(색상환의 반대쪽에 있는 색상)은 채도가 낮은 회색 중간점을 생성하는 경우가 많습니다.

/* Mixing orange-red and blue in sRGB */
color-mix(in srgb, #FF5733 50%, #3498DB 50%)
/* Result: a muted, somewhat brownish purple — [#9A77B7] range */

문제는 보색의 RGB 채널이 평균화될 때 서로 상쇄된다는 것입니다. 빨간색 [255, 87, 51]과 파란색 [52, 152, 219]는 [154, 120, 135]의 중간점을 생성합니다. 이는 채도가 낮고 회색으로 표시된 결과입니다.

HSL에서 혼합

HSL 블렌딩은 색상 휠을 따라 보간되므로 예상치 못한 중간 색상을 통한 색상 회전이라는 다른 문제가 발생할 수 있습니다.

/* Orange (hue ~15°) mixed with blue (hue ~210°) in HSL */
color-mix(in hsl, #FF5733 50%, #3498DB 50%)
/* Hue interpolates through ~112° — you get a greenish intermediate */

색상환에서 두 색상이 멀리 떨어져 있으면 HSL에서 두 색상 사이의 최단 경로가 녹색이나 기타 예상치 못한 색상을 통과할 수 있습니다. HSL은 또한 일반적으로 hsl()의 지각적 비균일성 문제를 공유합니다. 즉, 중간점 밝기가 두 소스 밝기 사이의 중간으로 보이지 않을 수 있습니다.

OKLCH에서 혼합

OKLCH 혼합은 대부분의 실제 사용 사례에 권장되는 접근 방식입니다. 이는 지각적으로 균일한 공간에서 보간됩니다. 즉, 중간 색상이 자연스러운 시각적 중간점처럼 보입니다. 즉, 생생하고 균형이 잡혀 있으며 예상치 못한 색조 드리프트가 없습니다.

/* Orange-red mixed with blue in OKLCH */
color-mix(in oklch, #FF5733 50%, #3498DB 50%)
/* Result: a vivid magenta-purple — perceptually halfway */

OKLCH에서 #FF5733(따뜻한 주황색-빨간색) 및 #3498DB(밝은 파란색)을 50/50으로 혼합하면 생동감 있고 포화된 중간체를 생성합니다. 색상은 보라색 범위를 통해 직접 보간됩니다. 이는 디자이너가 주황색과 파란색 사이의 "차이를 분할"하라는 요청을 받을 때 기대하는 것과 정확히 같습니다.

Oklab에서 혼합(Hue 더 짧음/더 긴 경로)

색상 보간을 위해 색상환 주위의 원호를 더 짧게 또는 더 길게 지정할 수도 있습니다.

/* Shorter hue path (default) */
color-mix(in oklch shorter hue, red, blue)

/* Longer hue path — goes the other way around the wheel */
color-mix(in oklch longer hue, red, blue)

/* Increasing hue */
color-mix(in oklch increasing hue, red, blue)

이 컨트롤은 특정 중간 색상을 통과하는 보간을 의도적으로 원할 때 유용합니다. 예를 들어 보라색이 아닌 빨간색에서 노란색, 파란색으로 진행되는 그라데이션과 같습니다.

비교표

색 공간 주황색 + 파란색 중간점 비주얼 캐릭터
srgb 음소거 된 회색 보라색 채도가 낮고 진흙투성이
hsl 녹색 예상치 못한 색조 변화
lab 보라색, 덜 선명한 sRGB보다 더 자연스럽다
oklch 선명한 마젠타-퍼플 지각적으로 가장 자연스러운

색상 변환기를 사용하여 특정 색상에 대한 OKLCH 값을 탐색하고 해당 값이 어떻게 혼합될지 예측하세요.

실제 사용 사례

호버 및 활성 상태 만들기

가장 즉각적으로 유용한 애플리케이션 중 하나는 각각에 대해 별도의 변수를 정의하지 않고 대화형 상태를 생성하는 것입니다.

:root {
  --btn-bg: oklch(0.55 0.22 250);  /* Your brand blue */
}

.btn {
  background-color: var(--btn-bg);
}

.btn:hover {
  /* Darken by 15% by mixing with black */
  background-color: color-mix(in oklch, var(--btn-bg) 85%, black);
}

.btn:active {
  /* Darken more for pressed state */
  background-color: color-mix(in oklch, var(--btn-bg) 70%, black);
}

.btn:disabled {
  /* Desaturate and lighten for disabled */
  background-color: color-mix(in oklch, var(--btn-bg) 40%, white);
  opacity: 0.6;
}

이렇게 하면 디자인 도구에서 세 가지 개별 색상을 선택하고 하드코딩할 필요가 없습니다. 호버 색상과 활성 색상은 베이스에서 수학적으로 파생되어 브랜드 색상이 변경되더라도 관계가 일관되게 유지됩니다.

의미론적 색상 척도 구축

디자인 시스템에는 브랜드 팔레트와 조화를 이루는 의미론적 색상(성공, 경고, 위험)이 필요합니다. color-mix()를 사용하면 브랜드 색상을 독립적으로 선택하는 대신 브랜드 색상에서 파생할 수 있습니다.

:root {
  --brand: oklch(0.55 0.22 250);  /* Brand blue */

  /* Success: mix brand with pure green to retain a hint of brand identity */
  --success: color-mix(in oklch, oklch(0.65 0.22 145) 85%, var(--brand) 15%);

  /* Warning: pure amber — no mix needed here */
  --warning: oklch(0.75 0.18 70);

  /* Danger: pure red */
  --danger: oklch(0.62 0.24 25);

  /* Tinted backgrounds for each state */
  --success-bg: color-mix(in oklch, var(--success) 12%, white);
  --warning-bg: color-mix(in oklch, var(--warning) 12%, white);
  --danger-bg:  color-mix(in oklch, var(--danger)  12%, white);
}

--success-bg는 성공 녹색의 매우 밝은 색조로 자동으로 파생됩니다. 알림 배너, 경고 상자 및 양식 필드 오류 상태에 대해 이를 사용합니다.

전체 음영 스케일을 동적으로 생성하기

Shade Generator는 정확한 인식 단계로 완전한 50-950 스케일을 생성하는 데 적합한 도구인 반면, color-mix()는 몇 가지 변형이 필요한 구성 요소에 대해 사용 가능한 근사치를 인라인으로 생성할 수 있습니다.

:root {
  --primary: oklch(0.58 0.20 250);

  --primary-50:  color-mix(in oklch, var(--primary) 8%,  white);
  --primary-100: color-mix(in oklch, var(--primary) 15%, white);
  --primary-200: color-mix(in oklch, var(--primary) 30%, white);
  --primary-300: color-mix(in oklch, var(--primary) 50%, white);
  --primary-400: color-mix(in oklch, var(--primary) 70%, white);
  --primary-500: var(--primary);
  --primary-600: color-mix(in oklch, var(--primary) 85%, black);
  --primary-700: color-mix(in oklch, var(--primary) 70%, black);
  --primary-800: color-mix(in oklch, var(--primary) 55%, black);
  --primary-900: color-mix(in oklch, var(--primary) 35%, black);
  --primary-950: color-mix(in oklch, var(--primary) 20%, black);
}

다크 모드 색상 파생

color-mix()는 다크 모드 표면 색상을 체계적으로 도출하는 데 특히 유용합니다.

@media (prefers-color-scheme: dark) {
  :root {
    --surface-base:     #09090b;
    --surface-elevated: color-mix(in oklch, var(--brand) 8%, #09090b);
    --surface-overlay:  color-mix(in oklch, var(--brand) 12%, #09090b);
  }
}

소량의 브랜드 색상을 어두운 표면에 혼합하면 미묘한 색조가 생성됩니다. 이는 Apple의 macOS 및 많은 최신 디자인 시스템에서 어두운 모드가 순수 중립 표면보다 덜 무미건조한 느낌을 갖도록 사용하는 기술입니다.

알파 채널 동작

백분율의 합이 100%가 아닌 경우 결과는 부분적으로 투명합니다. 이는 반투명 변형을 생성하기 위해 의도적으로 사용될 수 있습니다:

/* 30% blue on a transparent base — equivalent to rgba at 30% opacity */
color-mix(in srgb, blue 30%, transparent)

/* Also valid: named transparency from the other side */
color-mix(in oklch, #3B82F6 25%, transparent)

이는 rgba()를 고정 알파로 사용하는 패턴을 대체합니다. 장점은 혼합 비율에서 불투명도 관계가 명시적이며 순수한 투명도뿐만 아니라 모든 색상과 혼합할 수 있다는 것입니다.

브라우저 지원 및 대체

2026년부터 color-mix()는 다음에서 완벽하게 지원됩니다.

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

글로벌 지원이 90%를 초과합니다. color-mix() 결과를 볼 수 없는 사용자는 매우 오래된 모바일 브라우저나 브라우저 버전이 잠겨 있는 기업 환경을 사용하는 사용자입니다.

점진적인 향상 대체

CSS 사용자 정의 속성 선언 계단식. 브라우저가 color-mix()를 지원하지 않는 경우 이전 줄의 대체가 사용됩니다.

:root {
  /* Fallback for browsers without color-mix() */
  --btn-hover: #1D4ED8;

  /* Override with computed value for modern browsers */
  --btn-hover: color-mix(in oklch, var(--btn-bg) 85%, black);
}

사용자 정의 속성은 동일한 변수를 다시 선언하므로 이는 점진적인 향상 패턴으로 작동합니다. color-mix()를 지원하지 않는 브라우저는 명시적인 대체 색상을 사용합니다. 최신 브라우저는 파생된 값을 사용합니다.

또는 @supports를 사용하세요.

.btn:hover {
  background-color: #1D4ED8; /* Fallback */
}

@supports (color: color-mix(in oklch, red, blue)) {
  .btn:hover {
    background-color: color-mix(in oklch, var(--btn-bg) 85%, black);
  }
}

@supports 접근 방식은 결국 이전 브라우저 지원을 중단할 때 더 명확하고 정리하기가 더 쉽습니다.

주요 내용

  • color-mix()는 기본적으로 CSS에서 두 가지 색상을 혼합하므로 많은 사용 사례에서 JavaScript 또는 사전 생성된 음영 테이블이 필요하지 않습니다.
  • in <color-space> 인수는 블렌딩이 발생하는 위치를 제어하고 결과에 큰 영향을 미칩니다. 대부분의 작업에 oklch를 사용하십시오. 이는 흐릿한 불포화(sRGB 문제) 또는 예상치 못한 색상 변화(HSL 문제) 없이 지각적으로 자연스러운 중간점을 생성합니다.
  • 가장 실용적인 사용 사례는 대화형 상태(호버, 활성, 비활성화), 의미론적 색상 파생, 어두운 모드 표면 색조 및 단일 기본 변수에서 작은 음영 스케일 생성입니다.
  • 백분율 합계가 100% 미만이면 출력이 부분적으로 투명해 rgba() 없이 불투명 변형을 생성하는 데 유용합니다.
  • 브라우저 지원은 2023년 초 이후의 모든 최신 브라우저에 적용됩니다. 이전 CSS 선언 또는 이전 환경의 경우 @supports 블록 내에 하드코딩된 대체 값을 제공하세요.
  • 색상 변환기를 사용하여 기존 브랜드 색상을 OKLCH로 변환한 후 color-mix()에서 사용하고, 팔레트 생성기를 사용하여 CSS를 작성하기 전에 조화로운 색상 관계를 확인하세요.

관련 색상

관련 브랜드

관련 도구