学习前提

理解层叠、继承和颜色值;能阅读var()表达式。

本课完成后你能做什么

把重复样式值组织为可覆盖的变量,构建局部主题而不复制整套规则。

先理解机制

双短横线属性参与层叠并通常继承,var在使用位置解析。它们不是编译时简单文本替换:同一组件放在不同父级,可以继承不同主题值。把颜色命名为用途如--surface与--text,比按具体色名命名更适合主题变化。

在:root设置默认值,在主题容器覆盖,在组件中消费。变量数量以真实复用为依据,不必把每一个像素都抽成变量。局部覆盖可验证作用域是否正确:卡片变暗不应让整页导航同时改变。

var(--gap,16px)的回退处理未定义等情况,但变量存在且值不适合目标属性时,不会自动选第二项。例如给--gap赋red,再用于padding,会让声明失效。验证变量时既要检查是否存在,也要检查值在使用位置是否有效。

主题不仅是背景变黑,还包括正文、边框、链接、焦点和原生控件。color-scheme可提示浏览器适配原生控件。若产品提供手动选择,需明确与系统偏好谁优先;本例只展示局部主题,不持久化用户偏好。

可运行示例

运行方式:将HTML示例保存为独立的.html文件并在浏览器打开;含脚本的示例使用现代浏览器。资源文件与多文件模块另按正文要求准备。

<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Honeysuck practice</title></head><body>
<style>
:root{--surface:#fff;--text:#20362c;--border:#c7d5c9;--accent:#176343;--space:20px}
.theme-dark{--surface:#20362c;--text:#f6f8f0;--border:#789784;--accent:#c4e596;color-scheme:dark}
.card{padding:var(--space,16px);background:var(--surface);color:var(--text);border:1px solid var(--border);margin:16px 0;border-radius:12px}
.card a{color:var(--accent)}.card a:focus-visible{outline:3px solid currentColor;outline-offset:4px}
</style><article class="card"><h2>Light card</h2><a href="#next">Next lesson</a></article>
<section class="theme-dark"><article class="card"><h2>Dark card</h2><a href="#next">Next lesson</a></article></section><p id="next">Shared structure, different inherited tokens.</p>
</body></html>

推演与验证

两张卡片使用相同.card规则但颜色不同。在开发者工具修改暗色父级--space,只有该区域间距改变。将它设为red观察padding失效,再删除该覆盖恢复继承。检查焦点轮廓在两种背景中均可辨认。

常见错误与边界

变量不能直接用于普通媒体查询的条件。不要认为变量名隐藏了具体值就自动满足对比度要求;主题每种状态仍需要实际检查。

动手练习

增加紧凑卡片变体,只覆盖--space,不重写颜色规则。为打印提供白底黑字主题。

参考解法与理由

组件变体通过容器变量覆盖,打印在@media print中覆盖语义颜色。这样新增主题仍复用结构。验证打印预览,而不是只检查CSS文件有规则。

进一步阅读