CSS 变量和预处理器变量有什么区别?

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 价值 $200 的免费积分!

变量是 CSS 预处理器存在的首要原因之一。 能够为颜色等内容设置变量,并在编写的 CSS 中使用该变量,并确保它保持一致、干燥且易于更改非常有用。 您可以出于相同的原因使用本机 CSS 变量(“CSS 自定义属性”)。 但也有一些重要的差异需要明确。

预处理器变量使用的简单示例如下

$brandColor: #F06D06;

.main-header {
  color: $brandColor;
}
.main-footer {
  background-color: $brandColor;
}

这是 Sass 的 SCSS 变体,但所有 CSS 预处理器都提供了变量的概念:StylusLessPostCSS 等。

上面的代码在浏览器中不会执行任何操作。 浏览器不理解这些声明,会将它们丢弃。 预处理器需要编译成 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,其中包含更多详细信息。 数字表示该浏览器在该版本及更高版本中支持该功能。

台式机

ChromeFirefoxIEEdgeSafari
4931不支持1610

移动设备/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712710.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()` 一起使用来模拟布尔逻辑。