color-scheme 속성은 루트에 설정하는 것이 더 일반적이지만 개별 요소에 설정하여 페이지의 나머지 부분과 다른 색 구성표를 적용할 수도 있습니다.
이는 항상 특정 색 구성표 (예: 항상 어두운 모드 또는 밝은 모드)로 표시되어야 하는 구성요소에 유용할 수 있습니다.
사용 사례의 예를 들면 다음과 같습니다.
- 미적 이유로 밝은 모드 페이지에서도 어두운 모드로 표시되는 요소(예: 코드 블록, 미디어 플레이어, 사진 갤러리)
- 밝은 배경에 맞게 디자인된 미디어 (예: 이미지, 동영상, 삽화, 인쇄 미리보기)가 포함된 영역은 페이지의 나머지 부분이 어두운 모드인 경우에도 밝은 모드로 설정할 수 있습니다.
- 구성요소 프리뷰와 같이 사용자 수준 설정으로 색 구성표가 제어되는 요소
- 밝은 모드와 어두운 모드를 모두 지원하지 않는 삽입
- 디자인 도구, 지도, 시각화, 게임 등
색상을 변경해야 하는 경우와 color-scheme를 강제해야 하는 경우
밝은 모드에서 어두운 배경에 밝은 텍스트를 사용하거나 어두운 모드에서 밝은 배경에 어두운 텍스트를 사용하는 모든 요소에 다른 color-scheme가 필요한 것은 아닙니다.
예를 들어 기본 버튼은 밝은 모드에서 흰색 텍스트가 있는 파란색으로 렌더링될 수 있지만 color-scheme: dark를 보장하지는 않습니다.
일반적으로 다른 color-scheme를 사용하는 요소는 단순하고 얕은 컨테이너가 아니라 자체 시각적 컨텍스트를 설정하는 복잡한 표면입니다.
요소에 다른 color-scheme를 사용하는 것을 고려할 때는 다음 질문을 스스로에게 던져 보세요.
- 달리 맞춤설정되지 않은 기본 제공 브라우저 UI (예: 양식 컨트롤, 스크롤바 등)가 해당 색 구성표를 사용해야 하나요, 아니면 페이지의 색 구성표에 맞게 조정해야 하나요? -> 전자의 경우
color-scheme를 사용하지 마세요. light-dark()색상이 페이지의 나머지 부분과 같이 또는 재정의에 따라 확인되어야 하나요? -> 전자의 경우color-scheme를 사용하지 마세요.- 하위 요소가
color-scheme에 있어야 하나요? 그렇지 않은 경우color-scheme를 사용하지 마세요.
기본 구현
구성요소별 재정의는 일반적으로 (엄격하게는 아니지만) 전역 color-scheme를 통해 여러 색 구성표를 지원하는 페이지에서 사용됩니다.
페이지 전체에 어두운 모드를 올바르게 구현하려면 어두운 모드를 참고하세요.
페이지 전체 color-scheme가 설정되고 이에 민감한 색상 토큰을 사용하는 경우 (예: light-dark()를 통해) 특정 구성요소에 color-scheme를 설정하여 해당 하위 트리의 색상 모드를 재정의할 수 있습니다.
pre, code, .dark {
color-scheme: dark;
}
일부 브라우저는 구성요소를 다른 색 구성표에 자동으로 조정합니다.
모든 경우에 지정된 색 구성표를 강제 적용하려면 only(예: color-scheme: dark; 대신 color-scheme: only dark;)를 사용합니다.
색상이 아닌 값 조정
light-dark()는 현재 색상에만 작동합니다.
권장사항
- 필수: 배경이 없는 요소에는
color-scheme를 설정하지 마세요. 다른 색상 구성표의 배경과 텍스트 색상 쌍이 혼합되어 텍스트를 읽을 수 없게 될 수 있습니다. - 선택사항: 페이지 전체 어두운 모드와 동일한 색상 쌍을 재사용하는 것이 더 쉽지만 이러한 구성요소에 다른 색상 쌍을 정의할 수 있습니다. 예를 들어 밝은 모드 페이지에서 사용되는 어두운 모드 구성요소는 전체적으로 어두운 모드인 페이지에서 동일한 어두운 모드 구성요소가 사용되는 경우보다 약간 덜 어둡게 표시할 수 있습니다.
알려진 문제
중요한 주의사항: light-dark() 색상 상속
light-dark()는 계산된 값 시간에 확인됩니다.
즉, light-dark() 색상으로 설정된 상속된 <color> 속성은 light-dark() 표현식 자체가 아닌 두 색상 중 하나만 하위 요소에 전달합니다.
여기에는 다음이 포함됩니다.
- 상속되는 기본 제공 색상 속성(예:
color,accent-color,fill,stroke,text-shadow,caret-color) syntax: <color>및inherits: true가 있는 등록된 상속 가능한 맞춤 속성inherit로 설정된 다른<color>속성
즉, 다음을 수행해야 합니다.
- 디자인 토큰 (예:
--surface-color)을 보유하기 위한 맞춤 속성을<color>로 등록하지 않습니다. 하위 요소가 다른color-scheme에서 토큰을 다시 확인할 수 있도록 토큰은light-dark()표현식을 활성 상태로 유지해야 합니다. - 요소에
color-scheme를 설정할 때light-dark()값으로 설정되었을 수 있는 상속된<color>속성을 직접 또는 디자인 토큰을 통해 다시 지정합니다. 동일한 디자인 토큰에 지정하는 경우에도 마찬가지입니다. color-scheme재정의가 있는 요소의<color>속성에inherit를 사용하지 않습니다(하위 요소에 사용하는 것은 괜찮음).- 반대 사용 사례의 경우 등록된
<color>속성을 사용합니다. 즉, 상위 요소의 확인된 색상을 의도적으로 스냅샷으로 만들고 하위 요소의color-scheme에서 다시 확인되지 않도록 하려는 경우입니다. 예를 들어 다른 곳에서 사용할 페이지 배경을 캡처하는 경우입니다. - 색상에 애니메이션을 적용해야 하는 경우 애니메이션이 적용되는 요소에 별도의
@property등록<color>속성을 사용합니다 (색상 보간을 위해 등록이 필요함). 이는 디자인 토큰이 아니라 요소별 애니메이션 타겟이므로 위의 규칙과 충돌하지 않습니다.
예:
:root {
--accent-color: light-dark(blue, skyblue);
--surface-color: light-dark(white, #222);
--text-color: light-dark(#111, white);
color-scheme: light dark;
accent-color: var(--accent-color);
color: var(--text-color);
}
body {
/* --surface-color dynamically switches despite being inherited because --surface-color is not registered */
background: var(--surface-color);
}
pre, code {
color-scheme: dark;
background: var(--surface-color);
/* Without this, accent-color would be blue, not skyblue! */
accent-color: var(--accent-color);
/* Without this, text-color would be #111, not white! */
color: var(--text-color);
}
색 구성표를 사용할 때 주의해야 할 문제
- Chrome과 Firefox는 iframe의
color-scheme를 준수합니다. 즉, 삽입된 페이지를 올바른 색 구성표로 렌더링하고 삽입된 페이지의prefers-color-scheme미디어 쿼리를 조정하여 삽입 컨텍스트의color-scheme를 반영합니다. Safari는 그렇지 않으며 iframe 내부에서도prefers-color-scheme를 시스템 설정으로 확인합니다.- 상위 요소와 iframe을 모두 제어하는 경우: iframe 구성 시 URL 매개변수 (
?theme=dark)를 통해 또는postMessage()(런타임 변경사항에 반응할 수도 있음)를 통해 상위 요소의 색 구성표를 iframe에 명시적으로 전달합니다. iframe에서prefers-color-scheme에 의존하는 대신 해당 신호의<html>(또는:root의color-scheme)에 클래스를 설정합니다. - 삽입된 페이지만 제어하는 경우: Safari의 iframe 내에서 삽입 컨텍스트의
color-scheme를 감지하는 신뢰할 수 있는 방법이 없습니다. 삽입 API (예: 쿼리 문자열 또는postMessage프로토콜)에 명시적인 테마 매개변수를 노출하고 삽입자를 위해 문서화합니다.
- 상위 요소와 iframe을 모두 제어하는 경우: iframe 구성 시 URL 매개변수 (
대체 전략
color-scheme의 대체 및 브라우저 지원
color-scheme 속성은 점진적 개선입니다.
이를 지원하지 않는 브라우저는 이 속성을 무시하고 기본 밝은 모드 UI를 사용합니다.
이전 브라우저에서 사용자의 환경설정에 맞게 조정하려면 prefers-color-scheme 미디어 쿼리를 사용하여 어두운 모드가 선호될 때 다른 색상을 제공합니다.
- 미디어 쿼리를 사용하여
:root또는html에서 맞춤 속성을 전환합니다. - 구성요소에 색상 외에 매우 구체적인 유형의 어두운 모드 맞춤설정이 필요한 경우가 아니라면 개별 구성요소에 미디어 쿼리를 사용하지 마세요.
:root {
/* Define brand colors for each mode */
--color-brand-light: #0056b3;
--color-brand-dark: #00e5ff;
--color-brand: var(--color-brand-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--color-brand: var(--color-brand-dark);
}
/* Ignored in older browsers */
color-scheme: light dark;
}
button.primary {
background-color: var(--color-brand);
}
light-dark()의 대체 및 브라우저 지원
color-scheme는 지원하지만 아직 light-dark()는 지원하지 않는 브라우저의 경우, 먼저 색상의 밝은 버전과 어두운 버전을 맞춤 속성으로 정의해야 하며, 아래 예와 같이 prefers-color-scheme 미디어 쿼리를 사용하여 각 모드의 색상을 설정해야 합니다.
:root {
/* Define browser UI accent color for each mode */
--brand-accent-light: #0056b3;
--brand-accent-dark: #00e5ff;
--accent-color: var(--brand-accent-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--accent-color: var(--brand-accent-dark);
}
/* OPTIONAL: use light-dark() for more control of built-in UI colors */
@supports (color: light-dark(white, black)) {
--accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
}
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
/* Example inherited color property */
accent-color: var(--accent-color);
}
pre, code {
color-scheme: dark;
/* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
accent-color: var(--accent-color);
}