前端开发者学堂 - fedev.cn

CSS变量和预处理器变量的差异

发布于 薄荷

变量是CSS预处理器存在的主要原因之一。为某样东西设置变量的能力,比如颜色,在CSS中让变量保持一致,可DRY,并且易于改变是很有用的。出于相同原因,也可以使用原生CSS变量(“CSS自定义属性”)。但有一些重要的差异应该清楚。

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

$brandColor: #F06D06;

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

That was the SCSS variant of Sass, but all CSS preprocessors offer the concept of variables: Stylus, LESS, PostCSS, etc.

这是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);
}

这两个demo实现的是完全相同的效果。我们可以定义一次颜色值,多处使用。

那么,应该使用哪个呢?

为什么使用原生CSS自定义属性?

  • 无需使用预处理器就能使用它们
  • 可级联。可以在任何选择器中设置变量以设置或覆盖它的当前值。
  • 当它们的值改变(例如媒体查询或其他状态)时,浏览器根据需要重绘。
  • 可以在JavaScript中读取和操作它们。

关于级联,这有一个简单的例子:

:root {
  --color: red;
}
body {
  --color: orange;
}
h2 {
  color: var(--color);
}

所有<h2>的颜色都会变成orange,因为所有的<h2>都是<body>的子级,具有更高的适用特性。

甚至可以在媒体查询中重新设置变量,并让这些新值在它们使用的地方级联,这对于预处理器变量来说是不可能的。

看这个例子,它使用媒体查询改变了用来建立简单网格的变量:

Rob Dodson在CSS Variables: Why Should You Care?一文中提倡使用CSS的自定义属性

预处理器的变量有一个主要的缺点,它们是静态的,不能在运行时更改。增加在运行时更改变量的能力不仅打开了诸如动态应用主题的大门,同时对响应式设计及补充将来的CSS特性的潜力具有重大影响。

他引入了一个demo,使用JavaScript改变样式。然而它并不直接在元素上改变样式,而只是在运行时重置了一些CSS变量。

Wes Bos也有一个这样的demo:

注意我在这里忽略了一堆关于CSS自定义属性的东西。你可以设置回退。你可以使用calc()。有很多很酷的技巧可以使用。看下面的作业部分:

为什么使用预处理变量?

  • 从大处说:没有继承浏览器支持的注意事项。它们编译成正常的CSS。
  • 从小处来说:必要时可以把一个值的单位去掉。

可以同时使用它们

有相当多令人信服的理由同时使用这两个。你完全可以使用CSS预处理输出CSS自定义属性。Ivan Ivanov创建了一个demo,使用了CSS自定义属性的语法,并通过Sass,使得输出的代码可以回退。

我倾向于认为,一旦我们可以使用CSS自定义属性而不必担心浏览器支持,我们只是使用它们来做所有的变量处理。我们仍可能为了其他的方便而使用预处理语言,但原生的CSS处理变量似乎也很不错,值得一试。

CSS自定义属性的浏览器支持情况

这份关于浏览器支持的数据来自Caniuse,它也报告了这个特性处于W3C的候选推荐状态中。

作业时间:提升

1) 看Lea Verou的CSS Variables: var(--subtitle);

她覆盖了大量的实际应用和一些特技,比如控制变量级联和一些陷阱。

2)看 David Khourshid的CSS的反应动画

David分享的想法是,将CSS变量和DOM事件结合使用就能用不多的代码实现一些很棒的UI动画。看他的幻灯片([从#26开始)(http://slides.com/davidkhourshid/reactanim#/26)),真棒。

3) 看一看Harry Roberts的用自定义属性打造务实、实用和先进的主题

他的文章解释了使用CSS变量会令改变网站的用户主题容易得多。

4) 看Roman Komarov的 CSS变量的条件

尽管经常被讨论,但CSS中没有逻辑门(例如  @if (true) { })。我们有时候会用checked来伪造,但这取决于DOM。Roman shows off a trick一文(译文)中介绍了通过在变量上使用01,然后使用calc())来模拟布尔逻辑。

本文根据@CHRIS COYIER的《What is the difference between CSS variables and preprocessor variables?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://css-tricks.com/difference-between-types-of-css-variables/

薄荷

前端开发。喜欢看书,喜欢音乐。Let's share what we have。

如需转载,烦请注明出处:https://www.fedev.cn/css/difference-between-types-of-css-variables.htmlNike Magista Obra FG