부드러운 조명 및 어두운 모드 전환: 토큰, CSS 및 모션
시스템 설정을 존중하고, 로드 시 플래시를 방지하고, 기본 컨트롤의 스타일을 지정하고, 접근성을 손상시키지 않고 애니메이션을 적용하는 밝은/어두운 테마 스위치를 구축하는 방법입니다.
핵심 포인트
의미 체계 토큰에 테마를 구축하고, 기본적으로 Prefers-color-scheme을 사용하여 시스템 설정을 따르고, 사람들이 이를 재정의할 수 있도록 하고, 양식 컨트롤과 스크롤 막대가 일치하도록 색상 구성표 속성을 설정합니다. 플래시를 방지하려면 페이지가 렌더링되기 전에 저장된 테마를 적용하세요. 빠른 크로스페이드 또는 뷰 전환과 같은 스위치 애니메이션을 짧게 유지하고 모션 감소가 켜져 있으면 건너뜁니다.
시스템 설정에서 시작
선호 색상 구성표 미디어 기능은 사용자가 운영 체제에 밝은 테마 또는 어두운 테마를 요청했는지 여부를 알려줍니다. 이를 기본값으로 사용하고 이를 재정의하고 기억하는 인앱 스위치를 추가하세요.
재정의가 아닌 토큰이 포함된 테마
색상을 의미 토큰(표면, 텍스트, 테두리, 악센트)으로 정의하고 각 테마에 고유한 값(일반적으로 루트 요소의 CSS 사용자 정의 속성)을 제공합니다. 그러면 구성 요소가 테마 간에 변경되지 않습니다. 토큰 값만 그렇습니다. 이는 다중 브랜드 디자인 시스템에 사용되는 것과 동일한 3단계 토큰 접근 방식입니다.
기본 컨트롤을 잊지 마세요
MDN는 color-scheme 속성이 요소가 지원하는 구성표를 브라우저에 알려주고, 이는 양식 컨트롤, 스크롤 막대 및 기타 내장 UI의 기본 색상을 변경한다고 설명합니다. 이것이 없으면 어두운 페이지에 밝은 흰색 입력과 스크롤 막대가 표시될 수 있습니다.
로드 시 플래시를 피하세요
페이지가 렌더링된 후 저장된 테마가 JavaScript에 의해 적용되면 사람들은 잘못된 테마가 깜박이는 것을 보게 됩니다. 스타일시트가 그려지기 전에 문서 헤드의 작은 인라인 스크립트 또는 서버 렌더링 속성을 사용하여 가능한 한 빨리 적용하십시오.
스위치를 조심스럽게 애니메이션화하십시오.
약 150~250밀리초의 짧은 크로스페이드를 사용하면 의도적인 변경이 느껴지게 됩니다. 모든 요소의 모든 색상 속성을 전환하지 마십시오. 이는 큰 페이지에서 속도가 느려질 수 있습니다. 단일 뷰 전환 스냅샷이 더 부드러운 경우가 많습니다. 레이블이나 도구 설명을 사용하여 토글 자체를 명확하게 만들고 모션 감소가 켜져 있으면 애니메이션을 제거합니다.
프로덕션 구현 예시
/* Tokens per theme */
:root { color-scheme: light dark; --surface: #ffffff; --text: #121212; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) { --surface: #121212; --text: #f2f2f2; }
}
:root[data-theme="dark"] { color-scheme: dark; --surface: #121212; --text: #f2f2f2; }
:root[data-theme="light"] { color-scheme: light; }
body { background: var(--surface); color: var(--text); }
// Switch with a View Transition where supported, instantly otherwise
function setTheme(theme) {
const apply = () => { document.documentElement.dataset.theme = theme; localStorage.setItem('theme', theme); };
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!document.startViewTransition || reduce) return apply();
document.startViewTransition(apply);
}기억할 핵심 원칙
- 기본 색상 구성은 기본 설정입니다. 사람들이 그것을 무시하고 기억하게 하세요
- 구성 요소별 재정의가 아닌 의미 토큰이 포함된 테마
- 기본 컨트롤이 일치하도록 색 구성표를 설정하세요.
- 첫 번째 페인트 전에 저장된 테마 적용
- 스위치 애니메이션을 짧게 유지하고 감소된 동작을 존중합니다.
자주 묻는 질문
출처
- prefers-color-scheme — MDN 웹 문서
- color-scheme — MDN 웹 문서
- View Transition API — MDN 웹 문서