正在加载...

CSS 变量

滤镜改的是像素外观。自定义属性(CSS 变量)改的是维护方式::root 上一个 --brand,按钮读 var(--brand) — 改一次令牌,整站跟随。它们像普通属性一样层叠与继承,名字由你定。

自己起的名:--token

写法像普通声明,但名字必须以两个连字符开头:

:root 上的全局设计令牌

css
:root {
--brand: #2563eb;
--brand-contrast: #ffffff;
--surface: #f8fafc;
--text: #0f172a;
--radius-md: 0.5rem;
--space-3: 0.75rem;
}

:root 是文档根,常放全站令牌。任意选择器也可定义 --names;后代继承,除非更近处覆盖。

用 var() 读取

绑定令牌的主按钮

css
.btn-primary {
background: var(--brand);
color: var(--brand-contrast);
border: none;
border-radius: var(--radius-md);
padding: var(--space-3) calc(var(--space-3) * 1.5);
font: inherit;
cursor: pointer;
}

.btn-primary:hover {
background: color-mix(in srgb, var(--brand) 88%, black);
}

重点:令牌 + var()。项目里命名保持一致。

var() 中的回退值

缺少令牌时的回退

css
.card {
background: var(--surface, #ffffff);
color: var(--text, #111827);
border-radius: var(--radius-md, 8px);
box-shadow: var(--shadow-sm, 0 1px 2px rgba(15, 23, 42, 0.08));
}

第二个参数是备用;var() 里名字拼错,回退也救不了。

作用域与局部覆盖

📊 自定义属性放哪里

范围 典型选择器 何时
全局令牌 :root 品牌色、间距、圆角
组件主题 .card, .alert 一种模式的默认值
状态/变体 .card.is-warning 只换几个令牌
运行时 [data-theme="dark"] 换调色板;规则仍读同一 var(--surface)

在靠近需要变化的元素处覆盖。改 :root 影响全局;有时局部 --accent 更干净。

卡片上的局部 accent

自带 accent 的子树

css
.card {
--accent: var(--brand);
background: var(--surface);
border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
border-radius: var(--radius-md);
padding: var(--space-3);
}

.card.is-featured {
--accent: #7c3aed;
}

.card__title {
color: var(--accent);
}

.is-featured 只改 --accent;标题和边框通过 var() 跟上。

不换肤就 duplicate 每条颜色

默认浅色,data-theme 深色

css
:root {
--surface: #f8fafc;
--text: #0f172a;
--brand: #2563eb;
}

[data-theme="dark"] {
--surface: #0f172a;
--text: #e2e8f0;
--brand: #60a5fa;
}

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

JS 可改 dataset.theme — 令牌实时更新,无需重新编译 CSS。

自定义属性 vs Sass $

Sass $ 在构建时消失;--token 留在浏览器层叠里。

自己动手

  1. :root 五个令牌;按钮只用 var()。
  2. .card 设 --accent + .is-featured。
  3. 临时删掉令牌,用 fallback。
  4. DevTools 切换 [data-theme="dark"]。
  5. 把重复的 #2563eb 换成 var(--brand)。

常见错误

  • 写成 brand: 而不是 --brand:
  • 把 var() 当属性名
  • 拼错且无 fallback

小结

  • --name;var(--name, fallback)
  • :root 全局;组件局部覆盖
  • Modern Toolkit 下一节:calc

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
6
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部