튜토리얼

반응형 색상: 다양한 화면에 맞게 색상 적용

8분 읽기

반응형 디자인은 레이아웃 문제를 해결했습니다. 유동적인 그리드, 유연한 이미지 및 중단점을 통해 단일 코드베이스가 휴대폰 크기의 화면과 4K 모니터를 제공할 수 있게 되었습니다. 그러나 색상에는 CSS 그리드 및 미디어 쿼리가 원래 해결하도록 설계되지 않은 자체 반응 문제가 있습니다.

동일한 16진수 값이 iPhone OLED 화면, Windows 노트북 LCD, 보정된 전문가용 모니터 및 실외 디스플레이 패널에서 다르게 렌더링됩니다. 사용자는 밝은 환경과 어두운 환경 사이를 오가며 예측할 수 없는 상황에서 UI를 사용합니다. 넓은 색역 디스플레이는 sRGB가 전혀 표현할 수 없는 색상을 렌더링할 수 있습니다.

반응형 색상 디자인은 이러한 차이점을 이해하고 우연이 아닌 의도적으로 적응하는 글쓰기 스타일을 의미합니다.


디스플레이의 차이점과 중요한 이유

다양한 디스플레이 기술의 물리학

LCD(액정 디스플레이) — 대부분의 Windows 노트북, 저가형 모니터 및 구형 MacBook에서 볼 수 있습니다. LCD는 전체 화면을 백라이트로 사용하고 컬러 필터를 사용합니다. 검정색은 회색 빛을 띠며(백라이트가 새어 나옵니다) 색 영역은 일반적으로 sRGB이거나 그에 가깝습니다. 채도가 낮은 범위의 색상은 디자인한 방식과 비슷하게 보이는 경향이 있습니다.

OLED(유기발광다이오드) — iPhone Pro, Samsung Galaxy, Liquid Retina XDR이 탑재된 MacBook Pro, 고급 모니터. 각 픽셀은 자체 빛을 생성하므로 검은색은 진정한 검은색(광 출력 0)입니다. 색상은 LCD보다 더 생생하고 대비가 뚜렷하게 나타납니다. LCD의 미묘한 회색 배경은 거의 흰색으로 보일 수 있습니다. OLED에서는 뚜렷하게 어둡게 보일 수 있습니다.

IPS LCD ​​— 중급~고급 모니터. 기본 LCD보다 색상 정확도가 뛰어나고 시야각이 더 넓습니다. 종종 sRGB를 완전히 포함하고 때로는 DCI-P3까지 확장됩니다.

미니 LED — MacBook Pro 14/16 및 Pro Display XDR에 탑재된 Apple의 XDR 디스플레이입니다. 수천 개의 로컬 디밍 영역이 있는 LCD 패널을 사용합니다. 매우 높은 피크 밝기를 유지하면서 블랙 레벨 성능에서 OLED에 접근합니다. P3 색 영역을 표시합니다.

E-ink — Kindle 및 e-reader. 회색조 전용 또는 제한된 색상. 웹 앱에 대한 색상 디자인 결정은 여기서는 관련이 없지만 콘텐츠 가독성(대비)은 여전히 ​​중요합니다.

색 영역: sRGB, 디스플레이 P3 및 Rec. 2020

색재현율은 디스플레이가 생성할 수 있는 색상 범위입니다. 웹 디자인에서 접하게 될 세 가지 영역은 다음과 같습니다.

sRGB — 모든 모니터가 지원하는 표준 색역과 CSS가 역사적으로 가정한 색역입니다. #FF6B6B를 작성하면 브라우저는 이를 sRGB 색상으로 해석합니다. 브라우저와 OS는 해당 색상을 디스플레이에 매핑하는 것을 관리합니다.

디스플레이 P3 — sRGB보다 약 25~30% 더 넓습니다. 2016년경 이후의 모든 iPhone, iPad, Mac 디스플레이와 최신 Android 플래그십 및 일부 PC 모니터에서 지원됩니다. P3 영역은 특히 빨간색과 녹색 방향으로 확장됩니다. 즉, P3 디스플레이에서 생생하게 보이는 포화된 빨간색과 녹색은 sRGB에서는 전혀 표현할 수 없습니다.

** 추천. 2020** — P3보다 더 넓습니다. 주로 비디오 제작 및 HDR 콘텐츠와 관련이 있습니다. Rec.를 다루는 소비자 디스플레이는 거의 없습니다. 2020년 완전; 아직은 웹 UI 디자인의 실용적인 목표가 아닙니다.

P3 디스플레이에서 sRGB 색상을 사용하면 어떻게 되나요?

브라우저가 P3 디스플레이에서 #FF6B6B를 렌더링하면 운영 체제는 sRGB 색상을 P3 영역에 매핑합니다. 결과는 정확해 보입니다. 색상이 잘못된 것이 아닙니다. 당신이 얻지 못하는 것은 P3가 할 수 있는 확장된 활력입니다. 포화된 빨간색과 녹색은 sRGB 디스플레이에서와 동일한 시각적 강도로 생성됩니다.

P3의 더 넓은 범위를 활용하려면 P3 공간 색상을 명시적으로 지정해야 합니다. 그러면 브라우저는 sRGB 디스플레이에 맞게 적절하게 대체됩니다.


색상 적응을 위한 CSS 미디어 쿼리

prefers-color-scheme: 다크 모드

가장 널리 사용되는 색상 관련 미디어 쿼리는 사용자가 운영 체제에서 다크 모드를 활성화한 경우 팔레트를 조정합니다.

/* Light mode (default) */
:root {
  --color-bg: #F8FAFC;
  --color-surface: #FFFFFF;
  --color-text-primary: #1E293B;
  --color-text-muted: #64748B;
  --color-brand: #2563EB;
  --color-border: #E2E8F0;
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #0F172A;
    --color-surface: #1E293B;
    --color-text-primary: #F1F5F9;
    --color-text-muted: #94A3B8;
    --color-brand: #60A5FA;
    --color-border: #334155;
  }
}

다크 모드 브랜드 색상은 #2563EB(진한 파란색)에서 #60A5FA(연한 파란색)로 변경됩니다. 이는 의도적인 것입니다. 조명 모드 브랜드 파란색은 흰색 배경과 대비가 좋습니다. 짙은 남색 배경에서는 비슷한 대비를 유지하려면 더 밝은 값이 필요합니다.

대비 검사기를 사용하여 밝은 모드와 어두운 모드 조합을 모두 확인하세요.

  • 조명 모드: #F8FAFC#1E293B → 통과 확인 4.5:1
  • 다크 모드: #0F172A#F1F5F9 → 패스 확인 4.5:1
  • 다크 모드 브랜드 링크: #0F172A#60A5FA → 패스 확인 4.5:1

prefers-contrast: 고대비 모드

일부 사용자, 특히 시력이 약한 사용자는 OS에서 고대비 모드를 활성화합니다. prefers-contrast 미디어 쿼리를 사용하면 다음 기본 설정에 응답할 수 있습니다.

@media (prefers-contrast: more) {
  :root {
    --color-text-primary: #000000;
    --color-bg: #FFFFFF;
    --color-brand: #0000CC;
    --color-border: #000000;
  }
}

고대비 모드에서는 차분한 색상, 장식용 그라데이션 및 미묘한 색조를 뚜렷한 고대비 대체 요소로 바꿔야 합니다. 목표는 시각적 개선이 아닌 최대 가독성입니다.

prefers-contrast의 값에는 more, less, forcedno-preference가 포함됩니다. forced는 시스템 수준 색상 재정의를 적용하는 Windows 고대비 모드에 해당합니다. CSS 색상은 OS에 의해 완전히 재정의될 수 있습니다.

color-gamut: 넓은 범위의 디스플레이 타겟팅

color-gamut 미디어 쿼리는 사용자의 디스플레이가 sRGB보다 더 넓은 색 영역을 지원하는지 여부를 감지합니다.

/* Default: sRGB colors */
:root {
  --color-brand: #FF6B6B;
}

/* P3-capable displays: more vivid variant */
@media (color-gamut: p3) {
  :root {
    --color-brand: color(display-p3 1 0.35 0.35);
  }
}

color(display-p3 1 0.35 0.35) 구문은 display-p3 색상 공간과 함께 CSS color() 기능을 사용합니다. 값은 0~1 범위에 있습니다(0~100%에 해당). 이 특정 값은 sRGB가 표현할 수 있는 것보다 더 채도가 높은 빨간색에 매핑됩니다.

대부분의 UI 요소(텍스트, 배경, 테두리)의 경우 sRGB 영역이면 충분합니다. P3 색상의 사용 사례는 주로 브랜드 강조, 영웅 이미지, 유능한 디스플레이에서 최대의 생동감을 원하는 마케팅 요소입니다.

forced-colors: Windows 고대비 모드

Windows 고대비 모드는 스타일시트 색상을 시스템 정의 팔레트로 대체합니다. 요소는 모양과 레이아웃을 유지하지만 색상은 사용자가 선택한 고대비 테마(일반적으로 검정색 바탕에 흰색 텍스트, 흰색 바탕에 검정색 텍스트, 소수의 강조 색상 포함)로 재정의됩니다.

강제 색상 모드에서 표시되는 색상을 제어할 수는 없지만 인터페이스가 계속 작동하는지 확인할 수 있습니다.

@media (forced-colors: active) {
  /* Use system keyword colors */
  .button {
    background-color: ButtonFace;
    color: ButtonText;
    border: 2px solid ButtonBorder;
  }

  /* Restore borders on elements that relied on color alone */
  .status-indicator {
    border: 2px solid currentColor;
  }
}

ButtonFace, ButtonTextCanvas와 같은 CSS 키워드 색상은 사용자가 선택한 고대비 시스템 색상에 자동으로 매핑됩니다. 이를 사용하면 구성 요소가 파손되지 않고 의도적으로 보이도록 할 수 있습니다.


CSS 사용자 정의 속성을 사용한 동적 색상

반응형 색상을 위한 토큰 아키텍처

CSS 사용자 정의 속성(변수)은 반응형 색상 시스템의 기초입니다. 핵심 원칙: 구성 요소는 원시 값이 아닌 의미 체계 토큰을 참조합니다. 미디어 쿼리는 토큰 값을 변경합니다. 구성 요소를 업데이트할 필요가 없습니다.

/* Semantic tokens — these are what components use */
:root {
  /* Text */
  --text-primary: #1E293B;
  --text-secondary: #64748B;
  --text-inverse: #F1F5F9;

  /* Surfaces */
  --surface-base: #F8FAFC;
  --surface-raised: #FFFFFF;
  --surface-overlay: rgba(0, 0, 0, 0.04);

  /* Brand */
  --brand-primary: #2563EB;
  --brand-primary-hover: #1D4ED8;
  --brand-primary-text: #FFFFFF;

  /* Feedback */
  --color-error: #DC2626;
  --color-error-bg: #FEF2F2;
  --color-success: #16A34A;
  --color-success-bg: #F0FDF4;
}

@media (prefers-color-scheme: dark) {
  :root {
    --text-primary: #F1F5F9;
    --text-secondary: #94A3B8;
    --text-inverse: #1E293B;

    --surface-base: #0F172A;
    --surface-raised: #1E293B;
    --surface-overlay: rgba(255, 255, 255, 0.05);

    --brand-primary: #60A5FA;
    --brand-primary-hover: #93C5FD;
    --brand-primary-text: #0F172A;

    --color-error: #F87171;
    --color-error-bg: #1F0E0E;
    --color-success: #4ADE80;
    --color-success-bg: #0D1F12;
  }
}

구성요소는 토큰을 사용합니다.

.card {
  background-color: var(--surface-raised);
  color: var(--text-primary);
  border: 1px solid var(--color-border, #E2E8F0);
}

.button-primary {
  background-color: var(--brand-primary);
  color: var(--brand-primary-text);
}

사용자가 다크 모드로 전환하면 토큰 값이 변경되고 모든 구성 요소가 자동으로 업데이트됩니다.

페이지 새로고침 없이 인라인 테마 전환

사용자 정의 속성은 실시간으로 업데이트됩니다. 전체 페이지를 새로 고치지 않고도 테마 토글을 구현할 수 있습니다.

function toggleTheme() {
  const root = document.documentElement;
  const isDark = root.classList.toggle('dark-theme');

  // Override the prefers-color-scheme values
  if (isDark) {
    root.style.setProperty('--surface-base', '#0F172A');
    root.style.setProperty('--text-primary', '#F1F5F9');
    // ... all dark tokens
  } else {
    root.style.removeProperty('--surface-base');
    root.style.removeProperty('--text-primary');
    // Removing the overrides restores the media query values
  }

  localStorage.setItem('theme', isDark ? 'dark' : 'light');
}

사용자의 기본 설정을 localStorage에 저장하고 이를 페이지 로드 시(첫 번째 페인트 전) 적용하면 잘못된 테마가 깜박이는 것을 방지할 수 있습니다.

동적 색조에 color-mix() 사용

CSS color-mix()(2023년 현재 모든 최신 브라우저에서 지원됨)를 사용하면 모든 변형을 미리 계산하지 않고도 단일 기본 색상 토큰에서 색조와 음영을 만들 수 있습니다.

:root {
  --brand-base: #2563EB;
}

.badge {
  /* Mix brand color with white for a light tint */
  background-color: color-mix(in srgb, var(--brand-base) 15%, white);
  color: var(--brand-base);
}

.badge-dark {
  /* Mix with black for a darker variant */
  background-color: color-mix(in srgb, var(--brand-base) 85%, black);
  color: white;
}

이는 흰색 배경에 대한 브랜드 색상의 밝은 색조가 어두운 배경에 대한 어두운 색조가 되어야 하는 어두운 모드에서 특히 유용합니다. color-mix()를 사용하면 해당 관계를 토큰에서 한 번 정의하고 자동으로 조정할 수 있습니다.


화면 적응을 위한 색 공간 변환

반응형 색상에 16진수 코드가 충분하지 않은 이유

16진수 코드는 sRGB 색상을 나타냅니다. 여러 색상 공간(sRGB, 디스플레이 P3, OKLCH)에서 작업하는 경우 표현 간에 변환해야 합니다. 색상 변환기는 HEX, RGB, HSL, CMYK 및 OKLCH를 지원하므로 다음과 같은 경우에 유용합니다.

  • 색상의 HSL 밝기 값을 찾아 어두운 모드에서 색상이 어떻게 판독되는지 이해합니다.
  • 폴백을 위해 P3 색상을 가장 가까운 sRGB 근사값으로 다시 변환합니다.
  • 밝기 축이 실제로 지각적으로 균일한 OKLCH에서 작업합니다.

지각적으로 균일한 다크 모드 팔레트를 위한 OKLCH

OKLCH(Oklab Lightness, Chroma, Hue)는 밝기 축이 지각적으로 균일하기 때문에 반응형 색상 디자인에 점점 더 가치가 있습니다. 서로 다른 색조에서 동일한 밝기 변화가 극적으로 다른 결과를 생성하는 HSL과 달리 L의 동일한 숫자 단계는 인지된 밝기에서 시각적으로 동일한 단계를 생성합니다.

이는 다크 모드에 중요합니다. 라이트 모드 색상과 동일한 다크 모드를 생성해야 하는 경우 OKLCH를 사용하면 올바른 인식 밝기로 값을 더 쉽게 찾을 수 있습니다.

예를 들어 OKLCH의 조명 모드 음소거 텍스트 #64748B는 대략 oklch(53% 0.04 254)입니다. L 값 53%는 인지된 가벼움을 나타냅니다. oklch(13% 0.02 254)(L=13%, 어두운 배경)의 어두운 모드 표면의 경우 동등한 대비를 유지하기 위해 oklch(65% 0.04 254)(밝은 모드보다 약간 더 밝음)의 텍스트를 원할 수 있습니다.

색상 변환기를 사용하여 팔레트 색상의 OKLCH 값을 찾은 다음 다크 모드 대응물을 디자인할 때 해당 L 값을 가이드로 사용하십시오.


여러 장치에서 테스트

테스트 대상 및 이유

밝은 모드와 어두운 모드의 대비 — 두 모드 모두에서 모든 텍스트/배경 토큰 쌍에 대해 대비 검사기를 실행합니다. 밝은 모드에서 통과하는 색상은 어두운 모드에서 조정이 필요한 경우가 많습니다. 반전이 충분하다고 가정하지 마십시오.

단지 에뮬레이션이 아닌 실제 장치 — 브라우저 에뮬레이션 도구는 장치 크기를 시뮬레이션할 수 있지만 디스플레이 색상 속성을 정확하게 시뮬레이션할 수는 없습니다. iPhone OLED는 다크 모드와 채도에 중요한 방식으로 Windows 노트북 LCD와 다르게 색상을 렌더링합니다. 적어도 하나의 OLED 모바일 장치와 하나의 LCD 디스플레이에서 테스트하십시오.

OLED 대 LCD 어두운 배경 — ​​OLED에서 진한 남색 #0F172A는 실제 블랙 레벨과 함께 매우 어둡게 보입니다. 불량한 LCD에서는 눈에 띄게 더 가벼워 보일 수 있으며 시각적 계층 구조가 바뀔 수 있습니다.

보정된 모니터와 보정되지 않은 모니터 — 개발 모니터는 색상이 보정될 수 있습니다. 사용자의 모니터는 거의 확실하지 않습니다. 보정되지 않은 디스플레이에서는 색상이 더 따뜻하거나, 차갑거나, 다소 포화된 것처럼 보입니다. 이는 CSS에서 수정할 수 있는 사항은 아니지만 정확한 색상 정확도에 따라 매우 미묘한 색상 구별을 디자인해서는 안되는 이유를 알려줍니다.

고대비 모드 — 고대비 검정색 및 고대비 흰색을 활성화한 Windows에서 테스트합니다. OS가 색상 재정의를 적용한 후에도 모든 대화형 요소가 계속 작동하고 모든 텍스트를 읽을 수 있는지 확인하세요.

최소 장치 매트릭스

장치 디스플레이 유형 테스트하는 이유
iPhone 14 Pro 이상 OLED 다크 모드의 생동감, 블랙 레벨
안드로이드 플래그십(삼성 갤럭시) OLED iOS와의 색상 렌더링 차이점
맥북(2019+) P3 LCD 넓은 영역, macOS 색상 관리
Windows 노트북(일반) sRGB LCD 대부분의 사용자가 갖고 있는 기준선
Windows 데스크탑(모니터) sRGB 또는 광역 IPS 색상 정확도 참조

주요 내용

  • 다양한 디스플레이 기술(LCD, OLED, IPS, 미니 LED)은 서로 다른 블랙 레벨, 채도 및 생동감으로 동일한 16진수 값을 렌더링합니다. 브라우저 에뮬레이션뿐만 아니라 여러 물리적 장치에서 테스트합니다.
  • prefers-color-scheme는 다크 모드 적응을 위한 기본 미디어 쿼리입니다. CSS 사용자 정의 속성(토큰)을 추상화 레이어로 사용하면 테마가 변경될 때 구성 요소를 업데이트할 필요가 없습니다.
  • color-gamut: p3를 사용하면 color(display-p3 ...) CSS 기능을 사용하여 보다 생생한 색상으로 넓은 범위의 디스플레이를 타겟팅할 수 있으며 표준 디스플레이의 경우 sRGB로 자동 대체됩니다.
  • prefers-contrast: moreforced-colors: active는 각각 고대비 및 Windows 고대비 모드를 처리합니다. 이러한 설정이 필요한 사용자는 이 설정 없이는 제품을 사용할 수 없습니다.
  • OKLCH는 밝기 축이 모든 색상에 걸쳐 실제로 균일하기 때문에 지각적으로 균일한 팔레트를 디자인하는 데 가장 실용적인 색상 공간입니다. 이는 라이트 모드 팔레트와 동등한 다크 모드를 계산할 때 유용합니다.
  • 항상 밝은 모드와 어두운 모드 모두에서 대비를 확인하세요. 대비 검사기를 사용하세요. 밝은 모드에서 통과한 색상은 어두운 상황으로 바뀐 후 실패하는 경우가 많습니다.
  • 색상 변환기를 사용하여 다크 모드 대응물을 디자인하거나 16진수, HSL 및 OKLCH 표현 간 변환 시 색상 공간 전반에 걸쳐 작업할 수 있습니다.
  • 구성 요소에서 #1E293B가 아닌 --text-primary를 참조하는 의미론적 토큰 아키텍처는 모든 반응형 색상 시스템을 위한 확장 가능한 기반입니다. 토큰이 변경됩니다. 구성 요소는 그렇지 않습니다.

관련 색상

관련 브랜드

관련 도구