CSS light-dark() — 다크 모드를 한 줄로 표현하는 새 함수
한 속성에서 두 모드 색을 동시 표현. data-theme 중복 블록을 없애고 토큰을 한 줄로 비교 가능하게 만드는 표준 CSS 함수입니다.
다크 모드를 지원하려면 보통 [data-theme=dark] 같은 속성에 모든 색을 다시 정의해야 했습니다. CSS light-dark() 함수는 한 속성에서 두 모드 색을 동시에 표현하게 해줍니다. 코드량이 줄고, 속성이 흩어지지 않아 토큰을 한눈에 비교할 수 있습니다.
1. 기본 문법
1:root { 2 color-scheme: light dark; /* 두 모드 활성 선언 */ 3} 4 5body { 6 background: light-dark(#fff, #0a0a0f); 7 color: light-dark(#1a1a1a, #f8f9fb); 8}
color-scheme: light dark로 두 모드를 사용한다고 알리면, light-dark()가 사용자 선호(prefers-color-scheme)에 따라 알맞은 색을 반환합니다.
2. 토큰 정의 패턴
각 토큰을 한 줄에서 두 모드 다 정의합니다.
1:root { 2 color-scheme: light dark; 3 --bg: light-dark(#fff, #0a0a0f); 4 --fg: light-dark(#1a1a1a, #f8f9fb); 5 --card: light-dark(#f5f5f7, #131824); 6 --border: light-dark(#e5e5e7, #202d3f); 7 --accent: light-dark(#7c3aed, #8b5cf6); /* 다크에서 살짝 밝게 */ 8}
[data-theme="dark"] { --bg: ... } 식의 중복 블록을 만들 필요가 없습니다.
3. 사용자 토글 강제
OS 선호와 별개로 사용자가 선택할 수 있게 하려면:
1:root { color-scheme: light dark; } 2[data-theme=light]{ color-scheme: light; } 3[data-theme=dark] { color-scheme: dark; }
JavaScript에서 documentElement.dataset.theme = 'dark'로 설정하면 light-dark()가 그 모드 값을 사용합니다.
4. color-mix와 함께
light-dark() 결과를 또 섞을 수 있어, 다크 모드 hover도 한 줄로 처리됩니다.
1.btn { 2 background: var(--accent); 3} 4.btn:hover { 5 background: color-mix( 6 in oklch, 7 var(--accent) 88%, 8 light-dark(white, black) 9 ); 10}
라이트에서는 흰색 쪽으로, 다크에서는 검은색 쪽으로 보간되어 자연스럽게 hover가 표현됩니다.
5. 주의할 점
color-scheme을 선언하지 않으면 동작하지 않습니다. 폼 요소 등 OS 컨트롤도 이 속성을 참조합니다.prefers-color-scheme미디어 쿼리는 여전히 유효하지만,light-dark()가 더 간단한 경우가 많습니다. 복잡한 분기(폰트, 레이아웃 등 색이 아닌 변경)는 미디어 쿼리가 적절합니다.- 브라우저 지원: Chrome 123+, Safari 17.5+, Firefox 120+. fallback이 필요하면
prefers-color-scheme미디어 쿼리 안에서 같은 토큰을 다시 정의합니다.
1:root { 2 --bg: #fff; 3 --fg: #1a1a1a; 4} 5@media (prefers-color-scheme: dark) { 6 :root { --bg: #0a0a0f; --fg: #f8f9fb; } 7} 8@supports (color: light-dark(white, black)) { 9 :root { color-scheme: light dark; --bg: light-dark(#fff, #0a0a0f); --fg: light-dark(#1a1a1a, #f8f9fb); } 10}
6. 정리
| Before | After |
|---|---|
[data-theme=dark] { --bg: ... } 중복 블록 | --bg: light-dark(white, dark) 한 줄 |
| 미디어 쿼리 안에 색 재정의 | color-scheme 선언 + light-dark() |
| 토큰이 두 곳에 흩어짐 | 토큰 한 곳에 비교 가능 |
다크 모드가 토큰 정의의 일부가 되고, 코드가 평탄해집니다. 새 색을 추가할 때마다 두 곳에 적던 작업이 한 곳으로 줄어듭니다.
참고: MDN — light-dark() / W3C CSS Color Module Level 5.