How to Implement Dark Mode: Claude Code 활용 가이드
implement dark mode: Claude Code 활용. 실용적인 코드 예시와 단계별 가이드를 포함합니다.
ダークモード구현をClaude Code로 효율화하기
ダークモードは今やWeb앱の標準機能ですが、구현にはCSS설계、状態관리、永続化など多くの考慮が필요합니다。Claude Code를 사용하면一貫した설계で短시간で구현할 수 있습니다。
CSS변수에 의한테마설계
まずはCSS변수で테마토큰を定義します。
> CSS변수ベースでライト/ダーク테마を설계して。
> セマンティックな色名を使って、Tailwindと통합できるようにして。
/* globals.css */
:root {
--color-bg-primary: #ffffff;
--color-bg-secondary: #f8fafc;
--color-bg-tertiary: #f1f5f9;
--color-text-primary: #0f172a;
--color-text-secondary: #475569;
--color-text-tertiary: #94a3b8;
--color-border: #e2e8f0;
--color-border-hover: #cbd5e1;
--color-accent: #3b82f6;
--color-accent-hover: #2563eb;
--color-surface: #ffffff;
--color-surface-hover: #f8fafc;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
}
[data-theme="dark"] {
--color-bg-primary: #0f172a;
--color-bg-secondary: #1e293b;
--color-bg-tertiary: #334155;
--color-text-primary: #f1f5f9;
--color-text-secondary: #cbd5e1;
--color-text-tertiary: #64748b;
--color-border: #334155;
--color-border-hover: #475569;
--color-accent: #60a5fa;
--color-accent-hover: #93bbfd;
--color-surface: #1e293b;
--color-surface-hover: #334155;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
테마전환の구현
システム설정連動と手動전환の両方に대응するフックを作ります。
import { useState, useEffect, useCallback } from "react";
type Theme = "light" | "dark" | "system";
export function useTheme() {
const [theme, setThemeState] = useState<Theme>(() => {
if (typeof window === "undefined") return "system";
return (localStorage.getItem("theme") as Theme) || "system";
});
const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");
const applyTheme = useCallback((newTheme: Theme) => {
const root = document.documentElement;
let resolved: "light" | "dark";
if (newTheme === "system") {
resolved = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
} else {
resolved = newTheme;
}
root.setAttribute("data-theme", resolved);
setResolvedTheme(resolved);
}, []);
const setTheme = useCallback(
(newTheme: Theme) => {
setThemeState(newTheme);
localStorage.setItem("theme", newTheme);
applyTheme(newTheme);
},
[applyTheme]
);
useEffect(() => {
applyTheme(theme);
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = () => {
if (theme === "system") applyTheme("system");
};
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, [theme, applyTheme]);
return { theme, setTheme, resolvedTheme };
}
테마전환버튼
import { useTheme } from "@/hooks/useTheme";
export function ThemeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme();
const options: { value: Theme; label: string; icon: string }[] = [
{ value: "light", label: "ライト", icon: "sun" },
{ value: "dark", label: "ダーク", icon: "moon" },
{ value: "system", label: "システム", icon: "monitor" },
];
return (
<div className="flex items-center gap-1 p-1 rounded-lg bg-[var(--color-bg-tertiary)]">
{options.map((option) => (
<button
key={option.value}
onClick={() => setTheme(option.value)}
className={`px-3 py-1.5 rounded-md text-sm transition-colors ${
theme === option.value
? "bg-[var(--color-surface)] text-[var(--color-text-primary)] shadow-sm"
: "text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"
}`}
aria-label={option.label}
>
{option.label}
</button>
))}
</div>
);
}
FOUC(ちらつき)の防止
페이지로딩時に테마が一瞬切り替わるちらつきを防ぐスクリプトです。
<!-- head内に配置 -->
<script>
(function () {
const theme = localStorage.getItem("theme") || "system";
let resolved = theme;
if (theme === "system") {
resolved = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
}
document.documentElement.setAttribute("data-theme", resolved);
})();
</script>
Tailwind CSSとの통합
// tailwind.config.js
module.exports = {
darkMode: ["selector", '[data-theme="dark"]'],
theme: {
extend: {
colors: {
bg: {
primary: "var(--color-bg-primary)",
secondary: "var(--color-bg-secondary)",
tertiary: "var(--color-bg-tertiary)",
},
text: {
primary: "var(--color-text-primary)",
secondary: "var(--color-text-secondary)",
},
surface: {
DEFAULT: "var(--color-surface)",
hover: "var(--color-surface-hover)",
},
},
},
},
};
デザインシステムとの통합はデザインシステム구축を、반응형대응は반응형デザイン를 확인하세요.
정리
Claude Code를 활용하면 CSS변수설계、테마전환ロジック、FOUC防止、Tailwind통합まで、ダークモードの구현を一貫して短시간で완료할 수 있습니다。「ダークモード를 추가해줘」と依頼する만으로、既存프로젝트にも적절하게組み込めます。
자세한 내용은Claude Code공식 문서를 참고하세요.
무료 PDF: 5분 완성 Claude Code 치트시트
이메일 주소만 등록하시면 A4 한 장짜리 치트시트 PDF를 즉시 보내드립니다.
개인정보는 엄격하게 관리하며 스팸은 보내지 않습니다.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code용 CLAUDE.md 템플릿 7선 | 실제 프로젝트에 바로 붙여 넣는 예시
개인 앱, 콘텐츠 사이트, API, 팀 저장소, 레거시 코드베이스에 맞는 실전 CLAUDE.md 템플릿 7개와 피해야 할 실패 사례를 정리했습니다.
Claude Code Approval / Sandbox Guide | 매일 안전하게 쓰는 설정법
Claude Code의 allow, ask, deny, sandbox를 어떻게 나눌지, 실전 settings와 hooks, 실패 사례와 함께 정리합니다.
Claude Code 완벽 입문 가이드 2026 | 제로부터 실무 활용까지 7단계
Claude Code를 처음 사용하는 분들을 위한 완전 입문 가이드. 설치부터 실제 개발 워크플로우에 녹이는 것까지 — Masa가 처음에 겪었던 모든 시행착오를 바탕으로 정리했습니다.