Preferreds-color-scheme: 안녕 어둠, 내 오랜 친구

과장된 것인가요, 필수인가요? 어두운 모드와 사용자를 위해 어두운 모드를 지원하는 방법을 모두 알아보세요.

소개

어두운 모드 이전의 어두운 모드

검은색 배경에 녹색 텍스트가 표시된 1990년대 이전의 오래된 컴퓨터
그린 스크린 (소스)

어두운 모드는 한 바퀴 돌아 다시 돌아왔습니다. 개인용 컴퓨터가 처음 등장했을 때 다크 모드는 선택의 문제가 아니라 사실의 문제였습니다. 흑백 CRT 컴퓨터 모니터는 인광 스크린에 전자빔을 발사하여 작동했으며 초기 CRT에 사용된 인광 물질은 녹색이었습니다. 텍스트는 녹색으로 표시되고 나머지 화면은 검은색이었기 때문에 이러한 모델을 녹색 화면이라고 부르는 경우가 많았습니다.

Microsoft Word의 Windows 3.1 버전을 표시하는 모니터
흰색 배경에 검은색 (소스)

이후에 도입된 컬러 CRT는 빨간색, 녹색, 파란색 형광체를 사용하여 여러 색상을 표시했습니다. 세 가지 형광체를 모두 동시에 활성화하여 흰색을 만들었습니다. 더 정교한 WYSIWYG 데스크톱 게시가 등장하면서 가상 문서를 실제 종이처럼 보이게 만드는 아이디어가 인기를 끌었습니다.

초기 WorldWideWeb 브라우저에서 흰색 바탕에 검은색으로 표시된 웹페이지를 보여주는 창 클러스터
WorldWideWeb 브라우저 (소스)

디자인 트렌드로서 흰색 배경에 검은색이 시작된 곳이며 이 트렌드는 초기 문서 기반 웹으로 이어졌습니다. 최초의 브라우저인 WorldWideWeb(CSS는 아직 발명되지 않았음)은 웹페이지를 이런 방식으로 표시했습니다. 재미있는 사실: 두 번째 브라우저인 Line Mode Browser(터미널 기반 브라우저)는 어두운 배경에 녹색이었습니다. 요즘 웹페이지와 웹 앱은 일반적으로 밝은 배경에 어두운 텍스트로 디자인됩니다. 이는 Chrome을 비롯한 사용자 에이전트 스타일시트에도 하드코딩된 기본 가정입니다.

침대에서 휴대전화 사용

CRT 시대는 오래전에 끝났습니다. 콘텐츠 소비 및 제작이 백라이트 LCD 또는 에너지 절약형 AMOLED 화면을 사용하는 휴대기기로 이동했습니다. 더 작고 휴대하기 쉬운 컴퓨터, 태블릿, 스마트폰으로 인해 새로운 사용 패턴이 생겨났습니다. 웹 탐색, 재미를 위한 코딩, 고급 게임과 같은 여가 활동은 조명이 어두운 환경에서 근무 시간 외에 자주 이루어집니다. 밤에 침대에서 기기를 즐기는 사람도 있습니다. 어두운 곳에서 기기를 사용하는 사람이 많아질수록 어두운 배경에 밝은 텍스트로 돌아가자는 아이디어가 인기를 얻고 있습니다.

어두운 모드를 사용하는 이유

미적 이유로 어두운 모드

사람들에게 어두운 모드를 좋아하는 이유나 원하는 이유를 물으면 '눈에 편하다'는 대답이 가장 많고, 그 다음으로 '세련되고 아름답다'는 대답이 많습니다. Apple은 어두운 모드 개발자 문서에서 '밝은 모양을 사용할지 어두운 모양을 사용할지는 대부분의 사용자에게 미적인 선택이며 주변 조명 조건과 관련이 없을 수 있습니다.'라고 명시적으로 작성합니다.

'검은색 바탕에 흰색' 모드가 적용된 Mac OS 시스템 7의 CloseView (출처)

접근성 도구로서의 어두운 모드

어두운 모드가 필요한 사용자도 있습니다. 예를 들어 저시력 사용자는 어두운 모드를 또 다른 접근성 도구로 사용합니다. 이러한 접근성 도구 중 가장 오래된 것은 시스템 7CloseView 기능으로, 검은색 바탕에 흰색흰색 바탕에 검은색 간에 전환할 수 있었습니다. System 7은 색상을 지원했지만 기본 사용자 인터페이스는 여전히 흑백이었습니다.

이러한 반전 기반 구현은 색상이 도입되면서 약점을 드러냈습니다. 저시력 사용자의 컴퓨팅 기기 액세스 방법에 관한 Szpiro 의 사용자 연구에 따르면 인터뷰에 참여한 모든 사용자가 반전된 이미지를 싫어했지만 많은 사용자가 어두운 배경에 밝은 텍스트를 선호했습니다. Apple은 스마트 반전이라는 기능으로 이러한 사용자 환경설정을 수용합니다. 이 기능은 어두운 색상 스타일을 사용하는 이미지, 미디어, 일부 앱을 제외하고 화면의 색상을 반전합니다.

특수한 형태의 저시력은 컴퓨터 시력 증후군(디지털 눈 피로)으로, '데스크톱, 노트북, 태블릿을 비롯한 컴퓨터와 스마트폰, 전자 독서 기기 등의 기타 전자 디스플레이 사용과 관련된 눈 및 시력 문제의 조합'으로 정의됩니다. 청소년의 전자 기기 사용, 특히 야간 사용이 수면 시간 단축, 수면 시작 지연 증가, 수면 부족 증가의 위험을 높인다는 제안이 있었습니다. 또한 청색광 노출은 일주기 리듬 및 수면 주기의 조절과 관련이 있는 것으로 널리 보고되었으며, 불규칙한 조명 환경은 수면 부족으로 이어져 기분과 작업 수행 능력에 영향을 미칠 수 있다고 Rosenfield의 연구에 따르면 나타났습니다. 이러한 부정적인 영향을 제한하려면 iOS의 Night Shift 또는 Android의 야간 모드와 같은 기능을 통해 디스플레이 색상 온도를 조정하여 청색광을 줄이는 것이 도움이 될 수 있습니다. 어두운 테마나 어두운 모드를 통해 밝은 조명이나 불규칙한 조명을 피하는 것도 도움이 됩니다.

AMOLED 화면의 어두운 모드 절전 기능

마지막으로 어두운 모드는 AMOLED 화면에서 많은 에너지를 절약하는 것으로 알려져 있습니다. YouTube와 같은 인기 Google 앱에 초점을 맞춘 Android 사례 연구에 따르면 최대 60%의 전력 절감 효과를 얻을 수 있습니다. 아래 동영상에서 이러한 사례 연구와 앱별 절전 효과에 대해 자세히 알아보세요.

운영체제에서 어두운 모드 활성화

이제 어두운 모드가 많은 사용자에게 중요한 이유를 알아봤으니, 어두운 모드를 지원하는 방법을 살펴보겠습니다.

Android Q 어두운 모드 설정

어두운 모드 또는 어두운 테마를 지원하는 운영체제에는 일반적으로 설정에 이를 활성화하는 옵션이 있습니다. macOS X에서는 시스템 환경설정의 일반 섹션에 있으며 모양이라고 합니다 (스크린샷). Windows 10에서는 색상 섹션에 있으며 색상 선택이라고 합니다 (스크린샷). Android Q의 경우 디스플레이에서 어두운 테마 전환 스위치 (스크린샷)로 찾을 수 있으며, iOS 13에서는 설정의 디스플레이 및 밝기 섹션에서 모양을 변경할 수 있습니다 (스크린샷).

prefers-color-scheme 미디어 쿼리

시작하기 전에 마지막으로 이론을 살펴보겠습니다. 미디어 쿼리를 사용하면 작성자가 렌더링되는 문서와 관계없이 사용자 에이전트 또는 디스플레이 기기의 값이나 기능을 테스트하고 쿼리할 수 있습니다. CSS @media 규칙에서 문서를 조건부로 스타일링하는 데 사용되며 HTML, JavaScript와 같은 다양한 컨텍스트와 언어에서도 사용됩니다. 미디어 쿼리 레벨 5에서는 소위 사용자 환경설정 미디어 기능을 도입합니다. 즉, 사이트가 콘텐츠를 표시하는 사용자의 선호 방식을 감지하는 방법입니다.

prefers-color-scheme 미디어 기능은 사용자가 페이지에 밝은 색상 테마 또는 어두운 색상 테마를 사용하도록 요청했는지 감지하는 데 사용됩니다. 다음 값과 함께 작동합니다.

  • light: 사용자가 밝은 테마(밝은 배경에 어두운 텍스트)가 있는 페이지를 선호한다고 시스템에 알렸음을 나타냅니다.
  • dark: 사용자가 어두운 테마(어두운 배경에 밝은 텍스트)가 있는 페이지를 선호한다고 시스템에 알렸음을 나타냅니다.

어두운 모드 지원

브라우저에서 어두운 모드를 지원하는지 확인

어두운 모드는 미디어 쿼리를 통해 보고되므로 미디어 쿼리 prefers-color-scheme가 일치하는지 확인하여 현재 브라우저가 어두운 모드를 지원하는지 쉽게 확인할 수 있습니다. 값을 포함하지 않고 미디어 쿼리만 일치하는지 확인합니다.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

작성 시점을 기준으로 prefers-color-scheme는 버전 76 이상의 Chrome 및 Edge, 버전 67 이상의 Firefox, macOS의 버전 12.1 이상 및 iOS의 버전 13 이상의 Safari에서 데스크톱과 모바일 (사용 가능한 경우) 모두 지원됩니다. 다른 모든 브라우저의 경우 Can I use 지원 테이블 문서를 확인하세요.

요청 시 사용자의 환경설정 학습

Sec-CH-Prefers-Color-Scheme 클라이언트 힌트 헤더를 사용하면 사이트에서 요청 시 사용자의 색상 구성표 환경설정을 선택적으로 가져올 수 있으므로 서버에서 올바른 CSS를 인라인으로 처리하여 잘못된 색상 테마가 깜박이는 것을 방지할 수 있습니다.

어두운 모드 사용

마지막으로 어두운 모드를 지원하는 것이 실제로 어떤 모습인지 살펴보겠습니다. 하이랜더와 마찬가지로 어두운 모드에서는 하나만 있을 수 있습니다. 어두운 모드 또는 밝은 모드 중 하나만 가능하며 둘 다는 불가능합니다. 이 점을 언급하는 이유는 무엇인가요? 이 사실은 로드 전략에 영향을 미쳐야 하기 때문입니다. 사용자가 현재 사용하지 않는 모드의 중요한 렌더링 경로에 CSS를 다운로드하도록 강제하지 마세요. 따라서 로드 속도를 최적화하기 위해 다음 권장사항을 실제로 보여주는 예시 앱의 CSS를 중요하지 않은 CSS를 지연하기 위해 세 부분으로 분할했습니다.

  • style.css에는 사이트에서 보편적으로 사용되는 일반 규칙이 포함됩니다.
  • 다크 모드에 필요한 규칙만 포함하는 dark.css
  • light.css: 라이트 모드에 필요한 규칙만 포함합니다.

로드 전략

후자의 두 가지인 light.cssdark.css<link media> 쿼리를 사용하여 조건부로 로드됩니다. 처음에는 모든 브라우저가 prefers-color-scheme를 지원하지는 않습니다(위의 패턴을 사용하여 감지 가능). 따라서 조건부로 삽입된 <link rel="stylesheet"> 요소를 통해 기본 light.css 파일을 로드하여 동적으로 처리합니다(light는 임의로 선택한 것으로, dark를 기본 대체 환경으로 만들 수도 있음). 스타일이 지정되지 않은 콘텐츠가 깜박이는 현상을 방지하기 위해 light.css가 로드될 때까지 페이지 콘텐츠를 숨깁니다.

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

스타일 시트 아키텍처

CSS 변수를 최대한 활용하여 일반적인 style.css가 일반적일 수 있도록 하고 밝은 모드 또는 어두운 모드 맞춤설정은 다른 두 파일 dark.csslight.css에서 이루어집니다. 아래에서 실제 스타일의 발췌를 확인할 수 있지만 전체 아이디어를 전달하기에는 충분합니다. 밝은 배경에 어두운 텍스트어두운 배경에 밝은 텍스트 기준 테마를 만드는 두 변수 -⁠-⁠color-⁠-⁠background-color를 선언합니다.

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

그런 다음 style.css에서 body { … } 규칙에 이러한 변수를 사용합니다. :root CSS 의사 클래스에 정의되어 있으므로(HTML에서 <html> 요소를 나타내고 특수성이 더 높다는 점을 제외하고 html 선택자와 동일한 선택자) 캐스케이드되므로 전역 CSS 변수를 선언하는 데 유용합니다.

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

위의 코드 샘플에서 공백으로 구분된 값 light dark이 있는 속성 color-scheme을 확인했을 것입니다.

이렇게 하면 브라우저에 앱에서 지원하는 색상 테마가 표시되고 사용자 에이전트 스타일시트의 특수 변형을 활성화할 수 있습니다. 이는 예를 들어 브라우저가 어두운 배경과 밝은 텍스트로 양식 필드를 렌더링하거나, 스크롤 막대를 조정하거나, 테마 인식 강조 표시 색상을 사용 설정하는 데 유용합니다. color-scheme의 정확한 세부정보는 CSS 색상 조정 모듈 레벨 1에 명시되어 있습니다.

나머지는 사이트에서 중요한 항목에 대한 CSS 변수를 정의하는 문제일 뿐입니다. 스타일을 의미적으로 정리하면 어두운 모드에서 작업할 때 많은 도움이 됩니다. 예를 들어 -⁠-⁠highlight-yellow 대신 -⁠-⁠accent-color 변수를 호출하는 것이 좋습니다. 어두운 모드에서는 '노란색'이 실제로 노란색이 아닐 수 있기 때문입니다. 아래는 예시에서 사용하는 몇 가지 변수의 예입니다.

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

전체 예

다음 Glitch 삽입에서 위의 개념을 실제로 적용한 전체 예시를 확인할 수 있습니다. 특정 운영체제의 설정에서 어두운 모드를 전환하여 페이지가 어떻게 반응하는지 확인해 보세요.

영향 로드 중

이 예시를 사용해 보면 미디어 쿼리를 통해 dark.csslight.css를 로드하는 이유를 알 수 있습니다. 어두운 모드를 전환하고 페이지를 새로고침해 보세요. 현재 일치하지 않는 특정 스타일시트는 여전히 로드되지만 우선순위가 가장 낮으므로 지금 사이트에 필요한 리소스와 경쟁하지 않습니다.

어두운 모드 CSS가 가장 낮은 우선순위로 로드되는 방식을 보여주는 네트워크 로드 다이어그램(밝은 모드)
밝은 모드의 사이트가 우선순위가 가장 낮은 어두운 모드 CSS를 로드합니다.
어두운 모드에서 밝은 모드 CSS가 가장 낮은 우선순위로 로드되는 방식을 보여주는 네트워크 로드 다이어그램
어두운 모드의 사이트가 우선순위가 가장 낮은 밝은 모드 CSS를 로드합니다.
기본 밝은 모드에서 어두운 모드 CSS가 가장 낮은 우선순위로 로드되는 방식을 보여주는 네트워크 로드 다이어그램
prefers-color-scheme를 지원하지 않는 브라우저에서 기본 밝은 모드의 사이트는 우선순위가 가장 낮은 어두운 모드 CSS를 로드합니다.

어두운 모드 변경에 반응

다른 미디어 쿼리 변경사항과 마찬가지로 JavaScript를 통해 어두운 모드 변경사항을 구독할 수 있습니다. 이를 사용하여 페이지의 파비콘을 동적으로 변경하거나 Chrome에서 URL 표시줄의 색상을 결정하는 <meta name="theme-color">을 변경할 수 있습니다. 위의 전체 예시에서 이를 확인할 수 있습니다. 테마 색상과 파비콘 변경사항을 확인하려면 별도의 탭에서 데모를 여세요.

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

Chromium 93 및 Safari 15부터는 meta 테마 색상 요소의 media 속성을 사용하여 미디어 쿼리에 따라 색상을 조정할 수 있습니다. 일치하는 첫 번째 항목이 선택됩니다. 예를 들어 밝은 모드에 사용할 색상과 어두운 모드에 사용할 색상을 다르게 지정할 수 있습니다. 작성 시점에는 매니페스트에서 이를 정의할 수 없습니다. w3c/manifest#975 GitHub 문제를 참고하세요.

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

어두운 모드 디버깅 및 테스트

DevTools에서 prefers-color-scheme 에뮬레이션

전체 운영체제의 색상 구성표를 전환하면 금방 짜증이 날 수 있으므로 이제 Chrome DevTools를 사용하면 현재 표시된 탭에만 영향을 미치는 방식으로 사용자가 선호하는 색상 구성표를 에뮬레이션할 수 있습니다. 명령어 메뉴를 열고 Rendering를 입력하기 시작한 다음 Show Rendering 명령어를 실행하고 CSS 미디어 기능 prefers-color-scheme 에뮬레이션 옵션을 변경합니다.

Chrome DevTools의 렌더링 탭에 있는 'CSS 미디어 기능 prefers-color-scheme 에뮬레이션' 옵션의 스크린샷

Puppeteer로 prefers-color-scheme 스크린샷 찍기

PuppeteerDevTools 프로토콜을 통해 Chrome 또는 Chromium을 제어하는 고급 API를 제공하는 Node.js 라이브러리입니다. dark-mode-screenshot를 사용하면 어두운 모드와 밝은 모드에서 페이지의 스크린샷을 만들 수 있는 Puppeteer 스크립트가 제공됩니다. 이 스크립트를 일회성으로 실행하거나 지속적 통합 (CI) 테스트 모음에 포함할 수 있습니다.

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

어두운 모드 권장사항

순백색 피하기

순수한 흰색을 사용하지 않는다는 점을 눈치채셨을 수도 있습니다. 대신 주변의 어두운 콘텐츠에 대해 빛이 나고 번지는 것을 방지하기 위해 약간 더 어두운 흰색을 선택합니다. rgb(250, 250, 250)와 같은 표현이 적절합니다.

사진 이미지의 색상 변경 및 어둡게 하기

아래 두 스크린샷을 비교하면 핵심 테마가 어두운 배경에 밝은 콘텐츠에서 밝은 배경에 어두운 콘텐츠로 변경되었을 뿐만 아니라 히어로 이미지도 약간 다르게 표시됩니다. 사용자 조사에 따르면 설문조사에 참여한 대부분의 사용자는 어두운 모드가 활성화된 경우 약간 덜 생생하고 선명한 이미지를 선호하는 것으로 나타났습니다. 이를 다시 색칠하기라고 합니다.

어두운 모드에서 히어로 이미지가 약간 어두워집니다.
밝은 모드의 일반 히어로 이미지입니다.

이미지에 CSS 필터를 적용하여 다시 색칠할 수 있습니다. URL에 .svg가 없는 모든 이미지와 일치하는 CSS 선택자를 사용합니다. 벡터 그래픽 (아이콘)에 이미지 (사진)와 다른 색상 변경 처리를 적용할 수 있다는 아이디어입니다. 자세한 내용은 다음 단락을 참고하세요. 나중에 필터를 유연하게 변경할 수 있도록 CSS 변수를 다시 사용합니다.

다시 색상 지정은 어두운 모드에서만 필요하므로, 즉 dark.css가 활성 상태일 때만 필요하므로 light.css에는 상응하는 규칙이 없습니다.

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

JavaScript로 어두운 모드 다시 색상 지정 강도 맞춤설정

사람마다 다르며 어두운 모드에 대한 요구사항도 다릅니다. 위에 설명된 다시 색상 지정 방법을 고수하면 회색조 강도를 JavaScript를 통해 변경할 수 있는 사용자 환경설정으로 쉽게 만들 수 있으며, 0% 값을 설정하여 다시 색상 지정을 완전히 사용 중지할 수도 있습니다. document.documentElement는 문서의 루트 요소를 참조합니다. 즉, :root CSS 의사 클래스로 참조할 수 있는 동일한 요소입니다.

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

벡터 그래픽 및 아이콘 반전

벡터 그래픽(이 경우 <img> 요소를 통해 참조하는 아이콘으로 사용됨)의 경우 다른 색상 변경 방법을 사용합니다. 연구에 따르면 사람들은 사진의 반전을 좋아하지 않지만 대부분의 아이콘에는 매우 적합합니다. 여기에서도 CSS 변수를 사용하여 일반 상태와 :hover 상태의 반전 양을 결정합니다.

검은색 배경에 흰색 아이콘과 텍스트
어두운 모드에서는 아이콘이 반전됩니다.
흰색 배경에 검은색 아이콘과 텍스트
밝은 모드의 일반 아이콘

dark.css에서는 아이콘을 반전하지만 light.css에서는 반전하지 않으며, :hover는 사용자가 선택한 모드에 따라 아이콘이 약간 더 어둡거나 약간 더 밝게 표시되도록 두 경우에 서로 다른 반전 강도를 갖습니다.

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

인라인 SVG에 currentColor 사용

인라인 SVG 이미지의 경우 반전 필터를 사용하는 것 대신 요소의 color 속성 값을 나타내는 currentColor CSS 키워드를 활용할 수 있습니다. 이렇게 하면 기본적으로 값을 수신하지 않는 속성에서 color 값을 사용할 수 있습니다. 편리하게도 currentColor이 SVG fill 또는 stroke 속성의 값으로 사용되면 색상 속성의 상속된 값에서 값을 가져옵니다. 더 좋은 점은 <svg><use href="…"></svg>에서도 작동하므로 리소스를 분리해도 currentColor가 컨텍스트에 적용됩니다. 이는 인라인 또는 <use href="…"> SVG에만 적용되며 이미지의 src로 참조되거나 CSS를 통해 참조되는 SVG에는 적용되지 않습니다. 아래 데모에서 적용된 것을 확인할 수 있습니다.

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

모드 간 원활한 전환

colorbackground-color가 모두 애니메이션 가능한 CSS 속성이므로 어두운 모드에서 밝은 모드로 또는 그 반대로 전환하는 작업을 부드럽게 처리할 수 있습니다. 애니메이션을 만드는 것은 두 속성에 대해 두 개의 transition를 선언하는 것만큼 쉽습니다. 아래 예시에서 전반적인 아이디어를 확인할 수 있으며 데모에서 직접 체험해 볼 수 있습니다.

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

어두운 모드의 아트 디렉션

일반적으로 로드 성능상의 이유로 스타일시트에서 인라인이 아닌 <link> 요소의 media 속성에서만 prefers-color-scheme를 사용하는 것이 좋지만, HTML 코드에서 직접 인라인으로 prefers-color-scheme를 사용해야 하는 상황도 있습니다. 아트 디렉션이 이러한 상황에 해당합니다. 웹에서 아트 디렉션은 페이지의 전반적인 시각적 외관과 시각적으로 소통하고, 분위기를 자극하고, 기능을 대조하고, 타겟층에 심리적으로 어필하는 방식을 다룹니다.

어두운 모드에서는 디자이너의 판단에 따라 특정 모드에서 가장 적합한 이미지를 결정하고 이미지 다시 색상 지정충분하지 않을 수 있는지 결정합니다. <picture> 요소와 함께 사용하면 표시할 이미지의 <source>media 속성에 따라 달라질 수 있습니다. 아래 예에서는 어두운 모드의 경우 서반구를, 밝은 모드의 경우 또는 기본 설정이 없는 경우 동반구를 표시하며, 그 외의 모든 경우에는 동반구가 기본값입니다. 물론 이는 순전히 설명용입니다. 기기에서 어두운 모드를 전환하여 차이점을 확인하세요.

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

어두운 모드, 선택 해제 추가

위의 어두운 모드를 사용하는 이유 섹션에서 언급한 것처럼 어두운 모드는 대부분의 사용자에게 미적 선택입니다. 따라서 일부 사용자는 운영체제 UI를 어둡게 설정하는 것을 좋아하지만 웹페이지는 평소와 같은 방식으로 보는 것을 선호할 수 있습니다. 좋은 패턴은 처음에는 브라우저가 prefers-color-scheme를 통해 전송하는 신호를 따르지만, 이후에는 사용자가 시스템 수준 설정을 재정의하도록 선택적으로 허용하는 것입니다.

<dark-mode-toggle> 맞춤 요소

물론 이 코드를 직접 만들 수도 있지만, 이 용도로 제가 만든 기성 맞춤 요소 (웹 구성요소)를 사용해도 됩니다. <dark-mode-toggle>라고 하며, 완전히 맞춤설정할 수 있는 전환 버튼 (어두운 모드: 사용/사용 안함) 또는 테마 전환기 (테마: 밝음/어두움)를 페이지에 추가합니다. 아래 데모에서는 요소가 작동하는 모습을 보여줍니다. 또한 다른 에도 모두 몰래 🤫 추가했습니다.

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
밝은 모드의 <dark-mode-toggle>
어두운 모드의 <dark-mode-toggle>

다음 데모에서 오른쪽 상단의 어두운 모드 컨트롤을 클릭하거나 탭해 보세요. 세 번째 및 네 번째 컨트롤에서 체크박스를 선택하면 페이지를 새로고침해도 모드 선택이 기억되는 것을 확인할 수 있습니다. 이렇게 하면 방문자가 운영체제를 어두운 모드로 유지하면서 사이트를 밝은 모드로 즐기거나 그 반대로 할 수 있습니다.

결론

어두운 모드를 사용하고 지원하는 것은 재미있으며 새로운 디자인 방식을 열어줍니다. 일부 방문자에게는 사이트를 처리할 수 있는지 여부가 만족스러운 사용자가 되는지 여부를 결정할 수 있습니다. 몇 가지 주의사항이 있으며 신중한 테스트가 필요하지만, 다크 모드는 모든 사용자를 배려한다는 것을 보여줄 수 있는 좋은 기회입니다. 이 게시물에 언급된 권장사항과 <dark-mode-toggle> 맞춤 요소와 같은 도우미를 사용하면 멋진 다크 모드 환경을 만들 수 있습니다. 트위터에서 만든 콘텐츠와 이 게시물이 유용했는지, 개선을 위한 제안사항이 있는지 알려주세요. 읽어 주셔서 감사합니다. 🌒

prefers-color-scheme 미디어 쿼리 관련 리소스:

color-scheme 메타 태그 및 CSS 속성에 관한 리소스:

일반 어두운 모드 링크:

이 게시물의 배경 조사 자료:

감사의 말씀

prefers-color-scheme 미디어 기능, color-scheme CSS 속성, 관련 메타 태그는 👏 룬 릴레스벤의 구현 작업입니다. 룬은 CSS 색상 조정 모듈 레벨 1 사양의 공동 편집자이기도 합니다. 이 도움말을 철저히 검토해 주신 루카스 지빌루트, 로완 메레우드, 치라그 데사이, 롭 도드슨에게 🙏 감사의 말씀을 전합니다. 로딩 전략제이크 아치볼드의 아이디어입니다. Emilio Cobos Álvarez님이 올바른 prefers-color-scheme 감지 방법을 알려주셨습니다. 참조된 SVG와 currentColor가 포함된 팁은 Timothy Hatcher가 제공했습니다. 마지막으로 이 도움말의 권장사항을 만드는 데 도움을 준 다양한 사용자 연구의 익명 참여자 여러분께 감사드립니다.