핵심 개념
Tailwind CSS를 사용해 사이트에 다크 모드를 적용하는 방법.
다크 모드는 이제 많은 운영체제에서 퍼스트클래스 기능으로 자리 잡았습니다. 따라서 기본 디자인과 함께 웹사이트의 다크 버전을 디자인하는 것이 점점 더 일반화되고 있습니다.
Tailwind는 이를 쉽게 구현할 수 있도록 dark
변형을 제공합니다. 이 변형을 사용하면 다크 모드가 활성화되었을 때 사이트의 스타일을 다르게 지정할 수 있습니다.
라이트 모드
제로 그래비티 펜은 거꾸로 쓰기를 포함한 모든 방향에서 사용할 수 있습니다. 심지어 우주에서도 작동합니다.
다크 모드
제로 그래비티 펜은 거꾸로 쓰기를 포함한 모든 방향에서 사용할 수 있습니다. 심지어 우주에서도 작동합니다.
<div class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl">
<div>
<span class="inline-flex items-center justify-center p-2 bg-indigo-500 rounded-md shadow-lg">
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><!-- ... --></svg>
</span>
</div>
<h3 class="text-slate-900 dark:text-white mt-5 text-base font-medium tracking-tight">거꾸로 쓰기</h3>
<p class="text-slate-500 dark:text-slate-400 mt-2 text-sm">
제로 그래비티 펜은 거꾸로 쓰기를 포함한 모든 방향에서 사용할 수 있습니다. 심지어 우주에서도 작동합니다.
</p>
</div>
기본적으로 이 기능은 prefers-color-scheme
CSS 미디어 기능을 사용합니다. 하지만 ‘선택자’ 전략을 사용하여 수동으로 다크 모드를 전환할 수 있는 사이트를 구축할 수도 있습니다.
운영체제 설정에 의존하지 않고 수동으로 다크 모드를 전환하고 싶다면, media
전략 대신 selector
전략을 사용하세요.
selector
전략은 Tailwind CSS v3.4.1에서 class
전략을 대체했습니다.
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'selector',
// ...
}
이제 prefers-color-scheme
에 따라 dark:{class}
클래스가 적용되는 대신, HTML 트리에서 dark
클래스가 먼저 존재할 때마다 적용됩니다.
<!-- 다크 모드 비활성화 -->
<html>
<body>
<!-- 배경이 흰색으로 표시됨 -->
<div class="bg-white dark:bg-black">
<!-- ... -->
</div>
</body>
</html>
<!-- 다크 모드 활성화 -->
<html class="dark">
<body>
<!-- 배경이 검은색으로 표시됨 -->
<div class="bg-white dark:bg-black">
<!-- ... -->
</div>
</body>
</html>
Tailwind 설정에서 접두사(prefix)를 설정한 경우, dark
클래스에도 해당 접두사를 추가해야 합니다. 예를 들어, 접두사가 tw-
라면, 다크 모드를 활성화하기 위해 tw-dark
클래스를 사용해야 합니다.
html
엘리먼트에 dark
클래스를 추가하는 방법은 여러분의 선택에 달려 있지만, 일반적으로 localStorage
와 같은 곳에서 설정을 읽어와 DOM을 업데이트하는 JavaScript 코드를 사용하는 방법이 많이 쓰입니다.
일부 프레임워크(예: NativeScript)는 다크 모드를 활성화할 때 고유한 방식을 사용하며, 다크 모드가 활성화되면 다른 클래스 이름을 추가합니다.
darkMode
를 배열로 설정하고 두 번째 항목에 커스텀 선택자를 지정하여 다크 모드 선택자를 커스터마이징할 수 있습니다:
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['selector', '[data-mode="dark"]'],
// ...
}
Tailwind는 커스텀 다크 모드 선택자를 :where()
의사 클래스로 자동 감싸서, media
전략을 사용할 때와 동일한 우선순위 점수를 유지하도록 합니다:
.dark\:underline:where([data-mode="dark"], [data-mode="dark"] *){
text-decoration-line: underline
}
selector
전략을 사용하면 window.matchMedia()
API를 통해 사용자의 시스템 설정 또는 수동으로 선택한 모드를 모두 지원할 수 있습니다.
다음은 라이트 모드, 다크 모드, 그리고 운영체제 설정을 모두 존중하는 간단한 예제입니다:
// 페이지 로드 시 또는 테마 변경 시, FOUC를 피하기 위해 `head`에 인라인으로 추가하는 것이 좋음
document.documentElement.classList.toggle(
'dark',
localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
)
// 사용자가 명시적으로 라이트 모드를 선택할 때
localStorage.theme = 'light'
// 사용자가 명시적으로 다크 모드를 선택할 때
localStorage.theme = 'dark'
// 사용자가 명시적으로 OS 설정을 따르도록 선택할 때
localStorage.removeItem('theme')
이 설정은 여러분이 원하는 대로 관리할 수 있습니다. 심지어 서버 측 데이터베이스에 설정을 저장하고 서버에서 클래스를 렌더링하는 것도 가능합니다. 이는 전적으로 여러분의 선택에 달려 있습니다.
Tailwind의 기본 제공 다크 모드 변형을 여러분만의 커스텀 변형으로 대체하고 싶다면, variant
다크 모드 전략을 사용할 수 있습니다:
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['variant', '&:not(.light *)'],
// ...
}
이 전략을 사용할 때 Tailwind는 제공된 선택자를 어떤 식으로도 수정하지 않습니다. 따라서 선택자의 우선순위 점수를 주의 깊게 고려하고, 다른 유틸리티와 동일한 우선순위 점수를 보장하기 위해 :where()
의사 클래스를 사용하는 것을 고려해 보세요.
다크 모드를 활성화해야 하는 여러 시나리오가 있다면, 배열을 제공하여 모두 지정할 수 있습니다:
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['variant', [
'@media (prefers-color-scheme: dark) { &:not(.light *) }',
'&:is(.dark *)',
]],
// ...
}