본문 바로가기
Javascript

[Javascript] Tailwind와 함께 다크모드 구현

by 맨날개발 2025. 5. 17.

최신 브라우저에서는 다크모드 구현을 위한 기능들을 제공하고 있다. 그래서 간편하게 다크모드 기능을 구현할 수 있다.

 

다크모드 구현에 앞서 알아야 할 내용부터 정리를 해보자.

 

✅ color-scheme

MDN에서는 color-scheme을 사용하면 해당하는 색채 조합으로 웹페이지를 렌더링해준다고 설명하고 있다. 좀 더 쉽게 설명하면 light 또는 dark 로 설정된 값에 맞추어 시스템 전반에, 설정한 컬러 조합으로 렌더링해주는 것이다.

 

즉, color-scheme만 사용하면 간단하게 다크모드를 구현할 수 있다.

 

아래는 다크 테마를 적용한 예시이다. 해당 웹페이지는 다크 테마를 사용하겠다는 것을 브라우저에게 알려주는 내용이다. 그럼 브라우저는 다크 테마에 해당하는 컬러를 조합해서 각 요소들을 렌더링해준다.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      :root {
        color-scheme: dark;
      }
    </style>
  </head>
  <body>
    <p>안녕하세요</p>
    <input type="checkbox" />
  </body>
</html>

 

:root 에 등록하면 웹페이지 전체에 적용할 수 있다. 특정 요소에만 사용하고 싶은 경우에도 사용할 수 있다.

button {
  color-scheme: dark;
}

 

아래와 같이 color-scheme 설정하는 경우 웹페이지를 해당 컬러 조합을 사용하게 된다.

color-scheme: dark;
color-scheme: light;

 

사용자의 시스템에 적용된 속성으로 적용하고 싶은 경우 아래와 같이 사용하면 된다.

color-scheme: light dark;

 

✅ prefers-color-scheme

prefers-color-scheme CSS 미디어 특성은 현재 사용자가 사용하고 있는 테마를 탐지하는데 도움을 준다. 미디어쿼리를 사용해서 사용자의 시스템 테마에 맞추어 CSS를 작성할 수 있게 해준다.

@media (prefers-color-scheme: light) {
  p {
    color: red;
    background-color: white;
  }
}

@media (prefers-color-scheme: dark) {
  p {
    color: white;
    background-color: black;
  }
}

 

이때 주의해야할 점은 color-scheme을 사용해서 강제하더라도 prefers-color-scheme에는 영향을 주지 않는다.

prefers-color-scheme 미디어쿼리는 사용자가 설정한 테마에 따라서만 적용된다.

✨ 즉, 다크 모드 토글 기능을 구현해야한다면 prefers-color-scheme 미디어쿼리로만은 구현이 안된다.

 

 

💌 테일윈드를 사용해서 다크모드 구현

테일윈드에서는 다크모드를 위한 편의 기능들을 제공해준다. 이를 활용하면 다크 모드를 구현하는 방법은 정말 간단하게 구현할 수 있다.

 

✅ tailwind dark:

테일윈드에서는 기본적으로 prefers-color-scheme를 구현하는 방법을 제공해주고 있다. 사용자가 다크 테마를 사용하는 경우에 대한 스타일은 dark: 접두사를 사용하면 된다.

<div class="text-block dark:text-white">Hello World</div> 

 

위의 방법으로 각 테마에 맞는 스타일을 지정하면 끝이다.

 

✅ 다크 모드 토글 기능 구현

다크 모드의 토글 기능을 구현하기 위해서는 추가적인 작업이 필요하다.

 

기본적으로 dark 접두사는 prefers-color-scheme 의 설정에 따라서 적용된다. 즉, 사용자가 설정한 테마로만 적용된다.

토글 기능을 구현하기 위해서는 이 부분을 클래스명이 dark 이거나 data-theme=dark 인 경우에 적용되도록 변경해주어야 한다.

 

아래 두 가지 방법 중 하나를 선택해서 적용해주면 된다.

@custom-variant dark (&:where(.dark, .dark *)); // 클래스명으로 사용
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); // dataset으로 사용

 

두가지 중 하나를 적용하면 dark 클래스(data-theme가 dark인)를 가진 하위 트리에 dark 접두사를 사용하면 다크 모드를 사용할 수 있다.(클래스를 활용하는 것이 좀 더 간편)

✨ 클래스는 다크 모드 이외에도 다른 용도로 사용될 수 있기 때문에 이를 방지하려면 데이터셋을 활용하기!

 

 

만약 유저가 처음으로 웹페이지에 접속했다면 유저의 테마를 우선 적용해주는 것이 좋다. 이 때 유저의 테마 정보를 알아오는 방법은 다음과 같다.

window.matchMedia("(prefers-color-scheme: dark)").matches

 

 

지금까지의 모든 정보를 활용해서 토글 기능을 구현하면 다음과 같다.

document.documentElement.classList.toggle(
  "dark",
  localStorage.theme === "dark" ||
    (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches),
);

const button = document.querySelector('button');

const toggle = () => {
  const isDark = localStorage.theme === "dark";
	document.documentElement.classList.toggle("dark", !isDark);
	
	if (isDark) {
		localStorage.removeItem("theme");
	} else {
		localStorage.theme = "dark";
	}
}

document.addEventListener('click', toggle);

 

위의 코드의 흐름은 다음과 같다.

  1. 처음으로 웹페이지에 접속한다면 선호 색상으로 적용
  2. 아니라면 로컬 스토리지에 저장된 theme에 따라 dark 클래스 설정
  3. 토글 버튼 클릭 시 현재 다크 모드 값에 따라 클래스를 변경
  4. 다크 모드 값을 로컬 스토리지에 저장

 

✅ color-scheme를 사용한 다크모드

컬러조합을 브라우저에서 제공하는 컬러를 통해서 간단하게 다크모드를 구현하고 싶다면 테일 윈드의 color-scheme을 사용하면 된다.

 

테일윈드에서는 아래 클래스를 추가하면 해당 요소에 간단하게 적용할 수 있다.

scheme-dark
scheme-light
scheme-light-dark
<div class="scheme-light">
  <input type="date" />
</div>

 

아래와 같이 html에 추가해두고, 토글 기능만 구현하면 컬러 조합은 브라우저에서 제공하는 컬러를 사용해서 간단하게 구현할 수 있다.

<html class="scheme-light dark:scheme-dark">

</html>