안녕하세요 오늘은 웹페이지에 다크 모드 적용하는 방법에 대해 포스팅하겠습니다.
사용자들이 눈 건강을 위해 페이지 배경색을 어두운색(검정색)으로 변경하는 기능을 의미합니다.
본 게시글에서는 사용자가 직접 다크 모드를 on, off 할 수 있는 버튼을 제공해보도록 하겠습니다.
환경: React + Vite, Tailwind v4 (config-free).
1. Tailwind v4에서 클래스 기반 다크모드 켜기 - index.css
- v3처럼 tailwind.config.js의 darkMode: 'class'를 쓰지 않고, v4는 @custom-variant로 선언할 수 있습니다.
@import "tailwindcss";
/* v4: .dark 클래스 기반 다크 모드 활성화 */
@custom-variant dark (&:where(.dark, .dark *));
- 클래스 명에 dark 가 있을때 적용될 수 있도록 새 버전트(variant) 를 선언합니다.
- v4 의 경우 config-free 가 기본값으로, v3처럼 tailwind.config.js의 darkMode: 'class'가 아니라 CSS 안에서 선언해야합니다.
- 위 한줄로 인해 dark:bg-black, dark:text-white 같은 클래스를 어디서든 사용할 수 있습니다.
2. 전역 래퍼 - App.jsx
아래 div 태그로 App.jsx 에 있는 모든 요소를 감싸줍니다.
- 앱 최상단에 전역 컨테이너를 두고 라이트/다크의 기본 배경 및 텍스트 색을 지정할 수 있습니다.
<div className="min-h-screen bg-white dark:bg-black text-black dark:text-white transition-colors">
</div>
3. 다크모드 토글 컴포넌트 - DarkModeToggle .jsx
- 버튼 클릭시 html 에 dark 클래스를 토클하고 선택한 옵션을 로컬 스토리지에 저장함으로써, 캐시가 삭제되기 전까지 새로고침 혹은 재방문 시에도 다크 or 라이트 버전이 저장됩니다.
import { useEffect, useState } from "react"
export default function DarkModeToggle() {
const [dark, setDark] = useState(() => {
if (localStorage.getItem("theme")) {
return localStorage.getItem("theme") === "dark"
}
return window.matchMedia("(prefers-color-scheme: dark)").matches
})
useEffect(() => {
if (dark) {
document.documentElement.classList.add("dark")
localStorage.setItem("theme", "dark")
} else {
document.documentElement.classList.remove("dark")
localStorage.setItem("theme", "light")
}
}, [dark])
return (
<button
onClick={() => setDark(!dark)}
className="px-3 py-1.5 rounded-md border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700 text-black dark:text-white"
>
{dark ? "🌙 다크 모드" : "☀️ 라이트 모드"}
</button>
)
}
4. 토클 컴포넌트를 헤더에 배치.
- 위치는 자유롭게 두시면 됩니다.
- 현재 프로젝트의 경우 가장 맨위에 위치한 헤더에 위치하도록 합니다.
import DarkModeToggle from "./DarkModeToggle"
<header className="fixed top-0 w-full bg-white dark:bg-neutral-900 shadow-md z-50">
<div className="max-w-5xl mx-auto px-6 py-4 flex justify-between items-center">
<h1 className="text-xl font-bold text-indigo-600 dark:text-indigo-400">OOO.dev</h1>
<div className="flex items-center space-x-6 text-gray-700 dark:text-gray-200 font-medium">
<nav className="flex items-center space-x-6">
{/* ...Links... */}
</nav>
<DarkModeToggle />
</div>
</div>
</header>
오늘은 React + Vite + Tailwind v4 환경에서, @custom-variant로 클래스 기반 다크 모드를 활성화하고
전역 래퍼에서 토글 컴포넌트로 시스템 테마 + LocalStorage까지 연동하는 흐름을 구현해봤습니다.
시연 영상입니다.
'React' 카테고리의 다른 글
[React] 바깥 클릭 시 닫히는 드롭다운 (useOnClickOutside 훅) (1) | 2025.09.03 |
---|---|
[React] navigator.share + clipboard로 공유 버튼 간단 구현하기 (0) | 2025.08.25 |
[React] LottieFiles 애니메이션 적용하기 (0) | 2025.08.21 |
[React] 3D 아바타 컴포넌트 만들기 (0) | 2025.08.11 |
[React] 웹페이지 메뉴바 드롭다운 만들기 (0) | 2025.08.06 |