变量是 CSS 预处理器存在的首要原因之一。 能够为颜色等内容设置变量,并在编写的 CSS 中使用该变量,并确保它保持一致、干燥且易于更改非常有用。 您可以出于相同的原因使用本机 CSS 变量(“CSS 自定义属性”)。 但也有一些重要的差异需要明确。
预处理器变量使用的简单示例如下
$brandColor: #F06D06;
.main-header {
color: $brandColor;
}
.main-footer {
background-color: $brandColor;
}
这是 Sass 的 SCSS 变体,但所有 CSS 预处理器都提供了变量的概念:Stylus、Less、PostCSS 等。
上面的代码在浏览器中不会执行任何操作。 浏览器不理解这些声明,会将它们丢弃。 预处理器需要编译成 CSS 才能使用。 此代码将编译成
.main-header {
color: #F06D06;
}
.main-footer {
background-color: #F06D06;
}
现在这是一个有效的 CSS。 变量是预处理器语言的一部分,而不是 CSS 本身。 一旦代码编译完成,变量就会消失。
最近,本机 CSS 开始支持 CSS 变量或“CSS 自定义属性”。 它允许您直接在 CSS 中使用变量。 不需要编译。
CSS 自定义属性使用的简单示例如下
:root {
--main-color: #F06D06;
}
.main-header {
color: var(--main-color);
}
.main-footer {
background-color: var(--main-color);
}
这两个演示实现了完全相同的结果。 我们可以定义一次颜色并使用它两次。
那么… 为什么使用一个而不是另一个?
为什么要使用本机 CSS 自定义属性?
- 您可以**无需预处理器**使用它们。
- **它们级联**。 您可以在任何选择器内设置变量以设置或覆盖其当前值。
- 当它们的值发生变化(例如媒体查询或其他状态)时,**浏览器会根据需要重新绘制**。
- 您可以**在 JavaScript 中访问和操作它们**。
关于级联,这里有一个简单的示例
:root {
--color: red;
}
body {
--color: orange;
}
h2 {
color: var(--color);
}
任何<h2>
都会是橙色,因为任何<h2>
都是<body>
的子元素,它具有更高的适用特异性。
您甚至可以在媒体查询中重新设置变量,并让这些新值级联到所有使用它们的地方,这在预处理器变量中是不可能的。
查看 此示例,其中媒体查询更改用于设置非常简单的网格的变量

Rob Dodson 在 CSS 变量:为什么应该关心? 中倡导使用 CSS 自定义属性。
[预处理器] 使用的变量有一个主要缺点,它们是静态的,无法在运行时更改。 添加在运行时更改变量的能力不仅为动态应用程序主题打开了大门,而且对响应式设计以及将来填充 CSS 功能的潜力也具有重大意义。
他包括了一个 演示,其中 JavaScript 更改了样式。 它没有直接更改元素上的样式,而是在动态更改一些 CSS 变量。

Wes Bos 也有一个此功能的演示
查看 CodePen 上 Wes Bos (@wesbos) 的 使用 JS 更新 CSS 变量。
请注意,这里省略了很多关于 CSS 自定义属性的内容。 您可以设置回退。 您可以将它们与 calc() 一起使用。 您可以使用它们执行很多很酷的技巧。 请查看下面的作业部分!
为什么要使用预处理器变量?
- 最重要的原因是:没有浏览器支持方面的考虑。 它们会编译成正常的 CSS。
- 一些小细节:例如,如果需要,可以从值中去除单位。
您可以将它们一起使用
使用两者的理由非常充分。 您绝对可以使 CSS 预处理器输出 CSS 自定义属性。 Ivan Ivanov 创建了一个演示,允许您使用 CSS 自定义属性的语法进行编写,并通过 Sass 输出具有回退的代码
查看 CodePen 上 $i.van(ov) (@vank0) 的 立即使用 CSS4 变量。
我认为,一旦我们可以使用 CSS 自定义属性而不必担心浏览器支持,我们就可以使用它们来处理所有变量处理。 我们仍然可以使用预处理器来实现其他便利功能,但本机 CSS 中的变量处理似乎非常好,可能值得我们全力以赴。
CSS 自定义属性的浏览器支持
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。 数字表示该浏览器在该版本及更高版本中支持该功能。
台式机
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
49 | 31 | 不支持 | 16 | 10 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 10.0-10.2 |
作业时间:升级!
1) 观看 Lea Verou 的CSS 变量:var(–subtitle);
她涵盖了许多实际应用,以及一些技巧,例如控制变量级联的时间以及一些注意事项。
2) 观看 David Khourshid 的使用 CSS 进行响应式动画
David 分享了将 DOM 事件与 CSS 变量连接起来的想法,可以使用很少的代码来完成一些非常棒的 UI 工作。 查看他的幻灯片(从第 26 张开始),这些幻灯片展示了这有多么棒。
3) 阅读 Harry Roberts 的使用自定义属性进行务实、实用和渐进式主题化
他的文章解释了使用 CSS 变量如何使网站的用户主题变得非常容易。
4) 阅读 Roman Komarov 的CSS 变量的条件
尽管经常有人谈论,但 CSS 中没有逻辑门(例如:`@if (true) { }`)。我们有时会用类似 `:checked` 的东西来模拟,但这依赖于 DOM。 Roman 展示了一个技巧,你可以使用变量上的 `0` 或 `1`,然后与 `calc()` 一起使用来模拟布尔逻辑。
很棒的文章。自定义属性确实可以很好地用作 JS 操作的 API。
关于自定义属性,还有一个相关且值得注意的事情。声明一个像这样 `.--modifier` 的类名,将在 Safari Webkit 中破坏你的 CSS,因为它会将它视为自定义属性而不是类名。我使用这种命名约定来表示使用频率很高的全局修饰符,以避免在我的 BEM 组件中重复代码,结果发现,一旦 Safari 实现自定义属性的官方版本,我的很多 CSS 都在 Safari/iOS Webview 中失效了……
我不知道为什么它会被解析为自定义属性,因为点显然表示类名,在 CSS 中一直都是这样,因此应该优先于客户属性。我希望 Apple 在未来的版本中修复这个问题,不过现在已经这样了,总有可能这个版本的 Safari/Webkit 会有这个 bug 存在。
(在 safari 中查看这个 pen,看看我的意思) http://codepen.io/ericwshea/pen/ALwVPW
Safari 遵循 CSS 规范。我惊讶于其他浏览器允许这样做。
来源: https://www.w3.org/TR/CSS2/syndata.html#value-def-identifier
我强烈建议你 不要使用 `.--classname`,以防这种约定在将来用于其他东西,比如变量类名。
感谢你的信息!拍脑袋我应该检查文档。
是否有关于条件语句的文章链接?我想我可以直接谷歌搜索。
这篇文章已经更新了:http://kizu.ru/en/fun/conditions-for-css-variables/
感谢你的比较,Chris!CSS 变量的好处非常令人兴奋。
你忘记了 Roman Komarov 文章的链接,这是它:http://kizu.ru/en/fun/conditions-for-css-variables/
嗯,没有 ie/edge 支持:在生产环境中不可用。
请让你的博客更清晰。你可以在博客文章开头说明 caniuse 统计信息吗?(也许使用 Iframe,这样 caniuse 就可以自动更新)。
这篇文章的标题是“CSS 变量和预处理器变量有什么区别?”,而不是“CSS 变量是否可以让你在生产环境中使用?”。所以,你知道,为了清楚起见,我会先介绍一下,然后谈论浏览器支持。
我在博客文章中直接添加了 caniuse 数据,并且是以一种从那里直接提取最新数据并缓存的方式写成的(最多几天)。
哇!Chris 的文章很棒!我在前几天发布的文章中有一个使用 CSS 变量的主题切换器演示。另一个用例 :)
https://pawelgrzybek.com/css-custom-properties-explained/
我写过 去年关于 CSS 变量的文章(法语)。我举了两个例子,说明 CSS 变量如何能够很好地创建简单的 CSS 代码。
第一个例子是为不同颜色的块设置主题。相同的展示,但每次都有一个不同的主色。你可以看到 没有 CSS 变量的演示 和 有 CSS 变量的演示。比较这两个 CSS 文件(有 和 没有 变量)来查看使用 CSS 变量的代码有多清晰。
第二个例子是创建通用的精灵动画。你可以使用变量值创建一个动画。
然后设置变量值并调用这个动画。
比较一下这种技术的实时演示 没有 CSS 变量 和 有 CSS 变量。
我认为你不能在媒体查询中使用 CSS 变量。
感谢你的文章。
是不是只有我一个人,但我认为使用 Sass 很棒,因为它具有模块化性。如果他们只是简单地不那么一致地使用 CSS,人们在什么工作流程或项目中使用这些 CSS 变量会更有效率?
对我来说,在处理大型项目时,Sass 在这方面是一个巨大的优势。
看起来不错,但没有 IE 支持,所以不能用于生产环境 :/
是否有像 autoprefixer 这样的 PostCSS 插件可以解析 IE 的自定义属性,但允许 Chrome 和 Firefox 使用?
感谢你的文章。这可以用于 winLess 框架吗?
很棒的 CSS 技巧,有很多内容。
非常棒,信息量很大。