본문 바로가기
React

[React] Tailwind v4로 웹페이지 다크모드 설정하기 (클래스 기반)

by teamnova 2025. 9. 2.
728x90

안녕하세요 오늘은 웹페이지에 다크 모드 적용하는 방법에 대해 포스팅하겠습니다. 

 

사용자들이 눈 건강을 위해 페이지 배경색을 어두운색(검정색)으로 변경하는 기능을 의미합니다. 

본 게시글에서는 사용자가 직접 다크 모드를 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까지 연동하는 흐름을 구현해봤습니다.

 

시연 영상입니다.