CSS 變數 (Custom Properties)

CSS 變數(也稱為 Custom Properties)可以讓你定義可重複使用的值,方便維護和修改樣式。

定義變數

變數名稱以 -- 開頭:

:root {
  --primary-color: #007bff;
  --secondary-color: #6c757d;
  --font-size-base: 16px;
  --spacing: 20px;
}

:root 選擇器代表文件根元素(等同於 html),在這裡定義的變數可以在整份文件中使用。

使用變數

var() 函數取得變數的值:

.button {
  background-color: var(--primary-color);
  font-size: var(--font-size-base);
  padding: var(--spacing);
}

.text-secondary {
  color: var(--secondary-color);
}

預設值

var() 可以指定預設值,當變數未定義時使用:

.box {
  color: var(--text-color, black);
  padding: var(--box-padding, 10px);
}

變數作用域

變數遵循 CSS 的層疊規則,可以在不同選擇器中覆寫:

:root {
  --bg-color: white;
}

.dark-theme {
  --bg-color: #1a1a1a;
}

.container {
  background-color: var(--bg-color);
}

.container.dark-theme 內部時,會使用深色背景。

實用範例

主題顏色

:root {
  --color-primary: #007bff;
  --color-primary-dark: #0056b3;
  --color-secondary: #6c757d;
  --color-success: #28a745;
  --color-danger: #dc3545;
  --color-warning: #ffc107;
  --color-text: #333333;
  --color-bg: #ffffff;
}

.btn-primary {
  background-color: var(--color-primary);
}

.btn-primary:hover {
  background-color: var(--color-primary-dark);
}

間距系統

:root {
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-xxl: 48px;
}

.card {
  padding: var(--space-lg);
  margin-bottom: var(--space-md);
}

字體大小

:root {
  --font-size-xs: 12px;
  --font-size-sm: 14px;
  --font-size-md: 16px;
  --font-size-lg: 18px;
  --font-size-xl: 24px;
  --font-size-xxl: 32px;
}

h1 { font-size: var(--font-size-xxl); }
h2 { font-size: var(--font-size-xl); }
p { font-size: var(--font-size-md); }

深色模式

:root {
  --bg-color: #ffffff;
  --text-color: #333333;
  --border-color: #dddddd;
}

[data-theme="dark"] {
  --bg-color: #1a1a1a;
  --text-color: #f0f0f0;
  --border-color: #444444;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

.card {
  border: 1px solid var(--border-color);
}

也可以用媒體查詢自動切換:

@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #1a1a1a;
    --text-color: #f0f0f0;
  }
}

元件變數

在元件內部定義局部變數:

.card {
  --card-padding: 20px;
  --card-radius: 8px;
  
  padding: var(--card-padding);
  border-radius: var(--card-radius);
}

.card.compact {
  --card-padding: 12px;
}

計算值

變數可以和 calc() 一起使用:

:root {
  --base-size: 16px;
}

.large-text {
  font-size: calc(var(--base-size) * 1.5);
}

.double-spacing {
  padding: calc(var(--spacing) * 2);
}

用 JavaScript 操作變數

// 取得變數值
const root = document.documentElement;
const primaryColor = getComputedStyle(root).getPropertyValue('--primary-color');

// 設定變數值
root.style.setProperty('--primary-color', '#ff0000');

// 移除變數
root.style.removeProperty('--primary-color');

變數 vs Sass 變數

特性CSS 變數Sass 變數
執行時期瀏覽器(運行時)編譯時
動態修改可以不可以
JavaScript 存取可以不可以
層疊/繼承支援不支援
瀏覽器支援現代瀏覽器所有(編譯後)

注意事項

  • 變數名稱區分大小寫
  • 變數無法用於選擇器或屬性名稱
  • 變數值可以是任何有效的 CSS 值
/* 正確 */
:root {
  --my-color: blue;
}

/* 錯誤:不能用於屬性名稱 */
.box {
  var(--prop-name): blue;  /* 無效 */
}