Tailwind CSS Academy · 강의

CSS 변수 기반 테마 적용

디자인 토큰을 CSS 사용자 지정 속성으로 저장하고 Tailwind 설정에서 참조하여 다시 컴파일하지 않고도 런타임에 테마를 전환할 수 있도록 합니다.

레슨 2/413개 단계

CSS 변수 기반 테마 적용은(는) CoddyKit의 무료 Tailwind CSS Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Tailwind CSS Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Tailwind CSS Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Why CSS Variables for Theming?

CSS custom properties (CSS variables) are the key to runtime theming with Tailwind. Unlike static values baked into the compiled CSS, CSS variables can be changed by JavaScript at any time without reloading the page. This makes them ideal for implementing light/dark mode switches, user-selectable themes, or multi-tenant branding where the same application needs to look different for different clients.

Defining CSS Variables in :root

CSS variables are defined on the :root selector so they are globally available throughout the page. The syntax is --variable-name: value. You reference them with var(--variable-name). Place these definitions in your global CSS file — typically globals.css or index.css — so they are present before any component styles are applied.

/* globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --color-primary: #3b82f6;
    --color-primary-hover: #1d4ed8;
    --color-surface: #ffffff;
    --color-surface-alt: #f8fafc;
    --color-text: #111827;
    --color-text-muted: #6b7280;
    --color-border: #e5e7eb;
  }
}

Wiring CSS Variables Into Tailwind Config

Once your CSS variables are defined, you reference them in tailwind.config.js using the var(--variable-name) syntax. Tailwind will generate utility classes that use these variables as their values. When the variable changes at runtime, every generated class that references it updates automatically — no recompilation needed.

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: 'var(--color-primary)',
        'primary-hover': 'var(--color-primary-hover)',
        surface: 'var(--color-surface)',
        'surface-alt': 'var(--color-surface-alt)',
        'text-base': 'var(--color-text)',
        'text-muted': 'var(--color-text-muted)',
        border: 'var(--color-border)'
      }
    }
  }
}

Using Variable-Backed Classes in HTML

After wiring variables to Tailwind, your utility classes work exactly as before — the only difference is that the underlying value is now dynamic. Writing bg-surface applies background-color: var(--color-surface) to the element. Switch the variable value in CSS and every element using bg-surface updates without any HTML or JavaScript changes.

<div class="bg-surface text-text-base border border-border rounded-xl p-6">
  <h2 class="text-xl font-semibold text-primary mb-2">Card Title</h2>
  <p class="text-text-muted text-sm">This card adapts to any theme.</p>
  <button class="bg-primary hover:bg-primary-hover text-white px-4 py-2 rounded-lg mt-4">
    Action
  </button>
</div>

Dark Mode With CSS Variables

To implement dark mode, you override the CSS variable values under a .dark class on the root element. When JavaScript toggles the dark class on html, all variable values switch simultaneously, instantly updating every component. This approach requires zero additional Tailwind utilities beyond the initial variable-backed classes you already have.

@layer base {
  :root {
    --color-primary: #3b82f6;
    --color-surface: #ffffff;
    --color-text: #111827;
  }

  .dark {
    --color-primary: #60a5fa;
    --color-surface: #1e293b;
    --color-text: #f1f5f9;
  }
}

Opacity Support With CSS Variables

There is a subtlety with CSS variable colors and Tailwind's opacity modifier syntax. Utilities like bg-primary/50 require the color to be in RGB channel format so Tailwind can inject the alpha value. To support opacity modifiers, define your variables as RGB triplets without the rgb() wrapper and use the rgb(var() / alpha) pattern in the config.

/* globals.css — RGB triplet format */
:root {
  --color-primary-rgb: 59 130 246;
}

/* tailwind.config.js */
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: ({
          opacityValue
        }) => opacityValue
          ? 'rgb(var(--color-primary-rgb) / ' + opacityValue + ')'
          : 'rgb(var(--color-primary-rgb))'
      }
    }
  }
}

Multiple Theme Variants

CSS variables allow you to define multiple complete themes beyond just light and dark. Using data-theme attributes, you can scope different variable sets to different parts of the page or switch the entire application theme. This is particularly useful for multi-tenant SaaS applications where each customer brand needs its own color scheme from a shared codebase.

@layer base {
  [data-theme='ocean'] {
    --color-primary: #0ea5e9;
    --color-surface: #0c4a6e;
    --color-text: #e0f2fe;
  }

  [data-theme='forest'] {
    --color-primary: #16a34a;
    --color-surface: '#dcfce7';
    --color-text: #14532d;
  }
}

<!-- Switch theme with JS -->
document.documentElement.setAttribute('data-theme', 'ocean');

Animating Theme Transitions

When switching themes, a sudden color change can feel jarring. Adding a CSS transition on all properties to the root element creates a smooth color morph effect as variables change. Be selective — transitioning too many properties or using long durations can make the UI feel sluggish. A 150-300ms transition on color-related properties is typically ideal.

/* globals.css */
*, *::before, *::after {
  transition-property: color, background-color, border-color;
  transition-duration: 200ms;
  transition-timing-function: ease;
}

/* Exclude transitions from elements that should be instant */
.no-theme-transition,
.no-theme-transition * {
  transition: none !important;
}

Persisting Theme Preference

A theme switch is useless if it resets on page reload. Use localStorage to persist the user's preference and restore it on the next visit. The restoration script must run before the page renders to avoid a flash of the wrong theme. Place an inline script at the top of your HTML head — not in a module that loads after painting.

<!-- In <head> before any CSS -->
<script>
  (function() {
    var theme = localStorage.getItem('theme') ||
      (window.matchMedia('(prefers-color-scheme: dark)').matches
        ? 'dark' : 'light');
    document.documentElement.setAttribute('data-theme', theme);
    if (theme === 'dark') {
      document.documentElement.classList.add('dark');
    }
  })();
</script>

Semantic Variable Naming Patterns

Use a consistent naming pattern for your CSS variables to make them predictable and self-documenting. A three-part pattern of --category-role-state works well. For example: --color-action-default, --color-action-hover, --color-surface-raised, --color-feedback-error. Avoid vague names like --color1 or overly specific names like --signup-button-blue.

:root {
  /* Action colors */
  --color-action-default: #3b82f6;
  --color-action-hover: #1d4ed8;
  --color-action-disabled: #93c5fd;

  /* Surface colors */
  --color-surface-base: #ffffff;
  --color-surface-raised: #f8fafc;
  --color-surface-overlay: #f1f5f9;

  /* Feedback colors */
  --color-feedback-success: #16a34a;
  --color-feedback-error: #dc2626;
  --color-feedback-warning: #d97706;
}

Debugging CSS Variable Themes

When a themed color is not appearing correctly, the browser DevTools are your best friend. The computed styles panel shows the resolved value of any CSS variable on any element. You can also inspect :root directly to see all variable values. If you are seeing the raw var(--name) string instead of a color, the variable is not defined in the current scope — check for typos or missing :root blocks.

/* Quick debug: visualize all theme colors */
.theme-debug {
  background-color: var(--color-surface-base);
  color: var(--color-text-primary);
  border: 2px solid var(--color-border);
}

/* In DevTools console: */
/* getComputedStyle(document.documentElement)
   .getPropertyValue('--color-primary') */

Quick Check

Test your understanding of Tailwind CSS Mastery concepts from this lesson.

Lesson Recap

In this lesson you learned: CSS custom properties defined on :root serve as dynamic design tokens, Tailwind's config can reference them with var(--name) so generated classes inherit runtime changeability, and multiple themes are implemented by swapping variable values under different class or data-attribute selectors. Next up we explore multi-brand theming strategies for product teams.

무료로 시작

AI 튜터와 함께 HTML을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
30
레슨
120

자주 묻는 질문

“CSS 변수 기반 테마 적용” 강의는 무료인가요?

네 — “CSS 변수 기반 테마 적용” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Tailwind CSS Academy 강의 전체를 잠금 해제할 수 있습니다. Tailwind CSS Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“CSS 변수 기반 테마 적용”에서 뭘 배우나요?

디자인 토큰을 CSS 사용자 지정 속성으로 저장하고 Tailwind 설정에서 참조하여 다시 컴파일하지 않고도 런타임에 테마를 전환할 수 있도록 합니다. 브라우저에서 직접 실행하는 실습 코드로 Tailwind CSS Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Tailwind CSS Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Tailwind CSS Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“CSS 변수 기반 테마 적용” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Tailwind CSS Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Tailwind CSS Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 원시 토큰과 시맨틱 토큰 비교
  2. CSS 변수 기반 테마 적용
  3. 다중 브랜드 테마 전략
  4. 토큰 문서화 및 관리 체계
← Tailwind CSS Academy(으)로 돌아가기