Firefox Nightly 中的 CSS 变量

正如 Cameron McCormack 所述,Firefox Nightly(版本 29)现已支持 CSS 变量。您可以在此 简短的屏幕录制 中快速了解概况。

您可以使用 var- 前缀在上下文中定义变量,然后使用 var() 指令实现它们。例如

:root {
  var-companyblue: #369;
  var-lighterblue: powderblue;
}

h1 {
  color: var(companyblue);
}
h2 {
  color: var(lighterblue);
}

Header on page

Subheader on page

这为文档的根元素定义了两个变量 companybluelighterblue,结果为(您可以在此处尝试 使用 Firefox Nightly

变量是作用域化的,这意味着您可以覆盖它们

:root {
  var-companyblue: #369;
  var-lighterblue: powderblue;
}
.partnerbadge {
  var-companyblue: #036;
  var-lighterblue: #cfc;
}

h1 {
  color: var(companyblue);
}
h2 {
  color: var(lighterblue);
}

Header on page

Subheader on page

Header on page

Subheader on page

使用这些设置,具有 partnerbadge 类别的元素内部的标题现在将 获得其他蓝色设置

变量可以是您想要定义的任何值,您可以像使用其他任何值一样使用它们,例如在 calc() 计算中。您还可以将它们重置为其他值,例如在媒体查询中。 此示例 展示了其中许多可能性。

:root {
  var-companyblue: #369;
  var-lighterblue: powderblue;
  var-largemargin: 20px;
  var-smallmargin: calc(var(largemargin) / 2);
  var-borderstyle: 5px solid #000;
  var-headersize: 24px;
}
.partnerbadge {
  var-companyblue: #036;
  var-lighterblue: #369;
  var-headersize: calc(var(headersize)/2);
  transition: 0.5s;
}

@media (max-width: 400px) {
  .partnerbadge {
     var-borderstyle: none;
     background: #eee;
  }
}

/* Applying the variables */
body {font-family: 'open sans', sans-serif;}

h1 {
  color: var(companyblue);
  margin: var(largemargin) 0;
  font-size: var(headersize);
}
h2 {
  color: var(lighterblue);
  margin: var(smallmargin) 0;
  font-size: calc(var(headersize) - 5px);
}

.partnerbadge {
  padding: var(smallmargin) 10px;
  border: var(borderstyle);
}

尝试将窗口大小调整为小于 400 像素,以查看媒体查询更改的实际效果。

CSS 变量的初始实现刚刚在 Firefox Nightly 中发布,该版本目前为版本 29,在 2 月 3 日合并后,在 Firefox Aurora 中发布。在进入 Firefox Beta 和 Firefox 的发布周期之前,规范中还有一些部分需要支持。Cameron 有关这方面的详细信息

规范中尚未实现的唯一部分是 CSSVariableMap 部分,它提供了一个类似于 ECMAScript Map 的对象,并具有 getset 和其他方法,用于获取 CSSStyleDeclaration 上变量的值。但是请注意,只要您使用完整的属性名称(如 "var-theme-colour-1"),您仍然可以使用 getPropertyValuesetProperty 方法在 DOM 中访问它们。

此功能的工作是在 错误 773296 中完成的,感谢 David Baron 对此进行了审查,并感谢 Emmanuele Bassi 进行了部分初始实现工作。如果您在使用此功能时遇到任何问题,请 提交错误报告

现在,享受在 Nightly 中使用 CSS 变量的乐趣,并告诉我们您发现的任何问题。

关于 Chris Heilmann

HTML5 和开放网络的倡导者。让我们一起解决这个问题!

更多来自 Chris Heilmann 的文章…


46 条评论

  1. Brandon

    首先,恭喜您发布了这个功能。我们已经期待原生 CSS 变量很久了。

    但是,这种语法真的太冗长了。解析 Less 或 SASS 中的变量形式会太繁重吗?

    $foo 和 @bar 键入和阅读起来容易得多。

    2013 年 12 月 15 日 下午 09:29

    1. Chris Heilmann

      这是一个很好的反馈,可以提交给 W3C 在他们提供的开放邮件列表上。

      2013 年 12 月 15 日 下午 12:06

      1. Sebastian Zartner

        由于 CSS 变量(也称为自定义属性)的工作方式与 LESS 或 SASS 中的变量不同,因此无法重用它们的语法。
        而且据我所知,关于选择哪种语法的讨论已经持续了很久,他们最终同意了 “var-” 语法。

        2014 年 1 月 8 日 上午 06:15

  2. Trans

    W3C 又来了。当业界已经普遍使用(Less、Sass)的常见做法时,他们总是能创造出笨拙、丑陋的标准。

    2013 年 12 月 15 日 下午 10:13

    1. Chris Heilmann

      这似乎是对 W3C 发布的任何内容的常见本能反应。 “业界普遍做法”的概念是一种谬论。Flash 隧道曾经是常态,为什么没有一个元素?

      2013 年 12 月 15 日 下午 12:06

      1. Brian Kardell

        +Trans

        CSS 变量做的事情是预处理器无法做到的,反之亦然。它们之间存在重叠,但这些功能将使 CSS 变得更好,并将导致像 Sass 这样的工具在它们之上继续创新。它们还为那些 -使用- 选择器但本身不是 CSS 的事物开辟了新的领域。自定义属性是与众多利益相关者协商设计出来的,Sass 的维护者 Chris Eppstein 参与其中,并发挥了重要作用 - 这不是终点,而是起点。

        2013 年 12 月 15 日 下午 12:51

        1. m_gol

          我想说,CSS 变量可以做很多 Sass 变量无法做到的,反之则少。

          开发过程中的构建步骤,正如 Chris 提到的,对开发者来说是一项额外负担。我必须在浏览器中实验 CSS,然后将更改重新应用到我的 Sass 文件中,或者修改 Sass 文件并等待几秒钟才能在浏览器中看到更改,这会阻碍我的工作效率。我想在开发过程中消除这个中间人(像雪碧、串联、压缩等东西是需要的,但不是在开发过程中),以便更改能够立即反映出来。另一方面,即使在开发过程中,纯 CSS 对我的用例来说还是太有限了,所以我现在只能忍受所有这些额外的负担。

          2013 年 12 月 15 日 下午 13:33

  3. doug

    为什么这么冗长?

    2013 年 12 月 15 日 下午 11:42

  4. Tin Aung Lin

    酷,这意味着我们将来不需要任何 CSS 预处理器了。

    2013 年 12 月 15 日 下午 11:54

    1. Steve v

      CSS 预处理器做的不仅仅是变量….

      2013 年 12 月 15 日 下午 11:58

      1. Chris Heilmann

        当然,它们做更多的事情。许多事情,以不同的方式,并且作为构建过程的一部分。这就是赋予它们力量的原因,但也意味着对开发者的额外负担。

        2013 年 12 月 15 日 下午 12:03

        1. Moeed Mohammad

          对开发者来说,更大的负担是处理一些根本不需要存在的东西。这似乎是浪费时间 - 你的时间最好花在贡献给 Sass 上。

          2013 年 12 月 15 日 下午 13:36

          1. Chris Heilmann

            标准化使代码能够被所有人使用。我还没有见过一家支持 Sass 工作流程的企业公司。这不是用一种技术来替换另一种技术,而是为了发展我们很久以前就达成一致的标准。

            2013 年 12 月 15 日 下午 16:21

          2. Robert O’Callahan

            见下文;CSS 变量比任何预处理器所能提供的都强大得多。

            2013 年 12 月 15 日 下午 17:34

          3. m_gol

            @Moeed
            你搞错了。应该将预处理器中发现的优秀功能标准化。在开发过程中使用预处理器有很多缺点 - 耗时,与浏览器开发工具的集成效果更差等等。我们应该标准化那些已经成为既定实践的基元。

            此外,正如反复提到的,CSS 变量可以做很多任何预处理器都无法做到的事情。

            2013 年 12 月 15 日 下午 20:55

  5. cokeboys_run_ny

    我认为,现在由于这些变量可以作为混淆方法使用,并且可能为除了现有的 “expression” 和 “moz-binding”/等之外的方法评估脚本提供了新的方式,因此可能会出现新的 CSS 跨站点脚本攻击变体。

    2013 年 12 月 15 日 下午 11:56

    1. Chris Heilmann

      有趣的研究主题。这同样适用于自定义字体,我们是否想要放弃它们?每次运行时更改都是一个潜在的攻击点。

      2013 年 12 月 15 日 下午 12:04

    2. Robert O’Callahan

      不,这里没有新的方法来评估脚本。此外,您不能在 CSS 规则的属性名称一侧使用变量,因此它们不太可能给 CSS 清理器带来任何问题。

      2013 年 12 月 15 日 下午 17:33

  6. matt

    我期待着改造后的结果,最终你将拥有

    var-companyblue: #ff0

    2013 年 12 月 15 日 下午 13:17

  7. Moeed Mohammad

    为什么?

    Sass 已经实现了变量,并且功能更加丰富,而且实现方式更加有趣。这似乎完全没有必要。

    哦,而且语法丑陋不堪。

    2013 年 12 月 15 日 下午 13:34

    1. Chris Heilmann

      您的问题在于 W3C -> www-style@w3.org,主题行 “[css-variables] … 消息主题 …”

      2013 年 12 月 15 日 下午 16:22

    2. Robert O’Callahan

      CSS 变量支持对变量值进行脚本化的更改,使用选择器和媒体查询设置变量值(如本文所述!),以及沿着 DOM 层次结构继承变量值。根据定义,预处理器无法做到这些。

      2013 年 12 月 15 日 下午 5:31

  8. Bastian

    此功能可以实现什么,是 JavaScript 做不到的?

    2013 年 12 月 15 日 下午 1:41

    1. Doug

      首先,这是 CSS,而不是 JavaScript。但是,为什么要在 JavaScript 中设置 CSS 值?如果要设置许多元素的特定颜色或大小,你是否想要在 JavaScript 中执行此操作?

      2013 年 12 月 15 日 下午 2:42

      1. Bastian

        不,如果我想在 CSS 中设置许多元素的任何值,我会使用层叠...

        2013 年 12 月 15 日 下午 11:49

        1. m_gol

          层叠无法帮助你实现许多目标,例如在网站上的 100 个不同位置使用相同的颜色。除非你愿意在你的标记中添加大量非语义类。

          2013 年 12 月 17 日 上午 10:01

          1. Bastian

            我同意这使事情变得更容易,但代价是开发人员会对如今正确的 css 定义更加不注意......我使用 javascript 对元素进行动态更改,而不会更改 css 表格中的任何定义,只是根据类、id 或其他值,并且仍然在语义上可以接受。当我开始使用 web 技术的冒险之旅时,我了解到 css 表格是用于元素的定义,而服务器端程序/javascript 是用于逻辑的。现在事情要改变了。也许必须这样,一些新书需要写了。

            2013 年 12 月 17 日 上午 10:19

  9. marc fawzi

    这种语法让我想要呕吐。它是为机器而不是人设计的。这肯定会导致更多的人选择 CSS 预处理器路线。我能看到 sass/less 输出这种语法,但让用户使用预处理器更简单、更合乎逻辑的语法。

    2013 年 12 月 15 日 下午 4:07

    1. Chris Heilmann

      听到你胃不舒服的消息我很抱歉。我相信语法没有逐字照搬有非常合理的理由。进行一次采访了解情况会很有趣。

      2013 年 12 月 15 日 下午 4:19

      1. Marc Fawzi

        有趣。我今天确实得了流感。我认为这种负面反应主要是因为这些决定没有被放在语境中。

        2013 年 12 月 15 日 下午 4:47

  10. Alex

    我认为最大的问题是向后兼容性。

    如果我的“border-radius”在 IE8 中无法渲染,也没关系——我的图片只是有方形角。

    如果我理解正确,无法读取此代码的浏览器将为任何 CSS 变量获得一个空值。比如“background-color: null”。

    如果我们将其包含在浏览器中,我猜它可能在 3 年内准备好用于通用使用,但天啊,人们将在那时已经使用 Sass、Less 很长时间了,而且这些工作流程在那时可能已经相当成熟。

    尽管如此,我仍然喜欢看到像这样的东西。尝试和学习什么有效很重要。干得好,Chris。

    2013 年 12 月 15 日 下午 6:57

    1. m_gol

      它不会被解析为 null(无论如何 CSS 中没有这样的概念),整个规则将被删除,CSS 一直都是这样。这是一个很酷的功能,因为你可以轻松地降级

      background-color: black;
      background-color: var(dark-bg);

      还有其他 CSS 新功能不能优雅地降级,例如 Flexbox 或网格布局。但世界在前进。

      2013 年 12 月 15 日 下午 8:50

  11. poke

    人们似乎忽略了 CSS 变量与预处理器变量具有非常不同的语义。CSS 变量的范围由 DOM 树决定;变量的实际值只能针对 DOM 中的元素逐个进行评估。这使它们非常强大。如本文所示,甚至可以根据媒体查询更改这些值,这是一个令人难以置信的功能。

    预处理器变量无法做到这些。那些只是简单的变量,其范围仅限于选择器嵌套。它们被_一次性_处理,之后无法在运行时受到影响。你可以将它们视为简单的搜索和替换。

    两种类型的变量都有用;CSS 变量开辟了一系列全新的可能性,因此它们绝对值得实现。但由于它们的工作方式截然不同,因此使用完全不同的语法很有意义,这样它们就不会与编程语言或预处理器中已知的变量混淆。类似 CSS 属性的语法使这一点非常清楚,在我看来,这也很好地体现了它们的语义:它们是自定义 CSS 属性(以 var- 为前缀),像其他所有 CSS 属性一样被继承,并且可以使用 var 函数进行交叉引用。

    2013 年 12 月 15 日 下午 8:42

    1. Jérémy

      终于有人对此发表了明智的评论!

      谢谢

      2013 年 12 月 16 日 上午 1:10

  12. Niloy Mondal

    祝贺 Firefox 成为第一个实现此功能的浏览器。

    2013 年 12 月 15 日 下午 11:28

    1. Tim

      实际上,Chrome 已经实现了一段时间了,只是隐藏在 about:flags 标志后面(我认为是 Experimental CSS platform features 标志)。
      但是,Firefox 实现它是一件好事。

      2013 年 12 月 16 日 上午 12:12

  13. l2aelba

    .parent {
    color:#fff;
    .children {
    color:#000;
    }
    }

    这就是我在等待的(在原生 CSS 中)

    2013 年 12 月 16 日 上午 1:04

  14. Brian Knapp

    在我们进行更改时,Kivy 的 kv 语言中有一些用于指定数据绑定和窗口小部件树的功能,每当我回到没有这些功能的 web 编程时,这些功能都会让我非常痛苦。

    * 属性可以订阅。只是数据绑定。
    * 属性可以设置为类似于一些 CSS 编译工具链的表达式。
    * 表达式可以包含属性,如果其中的任何属性发生变化,整个表达式将被重新评估,从而本质上创建数据流行为。
    * CSS 规则可以设置为通过数据流更新的表达式。
    * 窗口小部件和布局(来自窗口小部件)的原型,允许嵌套本质上是模板化的 HTML 以及使用这些更高级别的窗口小部件而不是 div 汤来指定窗口小部件树。HTML 元素类似于 Kivy 图形指令,其功能与普通的 Image 窗口小部件相同。
    * 窗口小部件和布局(来自窗口小部件)的原型,允许嵌套本质上是模板化的 HTML 以及使用这些更高级别的窗口小部件而不是 div 汤来指定窗口小部件树。HTML 元素类似于 Kivy 图形指令,其功能与普通的 Image 窗口小部件相同。

    这些东西在 Kivy 中非常棒,以至于我真的对 web 产生了一种恐惧,这在我的灵魂深处或可能靠近我的阑尾。如果没有一些重大变化来满足其他 UI 编程范式,我真的不知道如何喜欢 web 编程。

    基本上,我要求扔掉孩子和洗澡水,以便用我所熟悉的完全相同的东西来代替它们,但这几乎是圣诞节了,圣诞老人是我的首选神灵。所有赞美圣诞老人。我们崇拜圣诞老人。

    2013 年 12 月 16 日 下午 4:35

    1. Robert Nyman [编辑]

      欢迎你向 W3C 建议这些想法,如果得到了响应,它们将被标准化。

      2013 年 12 月 17 日 上午 4:19

  15. abs

    css 变量的标准化是我多年来一直在等待的。祝贺 mozilla 迈出了这一步。顺便说一句,我也认为这种方法太冗长了。

    2013 年 12 月 16 日 下午 6:52

  16. Vishnu Haridas

    你为什么还不标准化它?这个宇宙中的所有 web 开发人员都在等待它!

    2013 年 12 月 19 日 上午 10:06

  17. Alex Bell

    “var”真的比“$”冗长很多吗?它无疑更具语义,而且有更深厚的历史先例。此外,如前所述,“实时”DOM 范围与 SASS 中的任何东西都完全不同。我认为 W3C 实际上在各个方面都做对了。干杯!

    2013 年 12 月 19 日 上午 11:37

  18. David Baughman

    SASS、LESS、MOAR!胡说八道胡说八道......

    说实话,将预处理器与 CSS 本身进行比较是不公平的。使用预处理器可以做很多事情,这些事情可能永远不会成为核心 CSS 规范的一部分。此外,预处理器可以比规范更改更频繁地进行功能更新。因此,如果你想追随最新的潮流,就坚持使用预处理器。如果预处理器让你害怕,那么今年你会得到一个很棒的圣诞礼物,那就是变量 =)

    也就是说,这些更新应该使预处理器的工作更容易。谁知道呢,也许 LESS/SASS 编译后的 CSS 文件会因此变小。

    2013 年 12 月 19 日 下午 12:51

  19. Daniel

    丑陋的语法。:(

    2013 年 12 月 20 日 上午 8:11

  20. Jonathan Prates

    为什么不行?

    :root {
    companyblue = #369;

    我认为 = 比 var- 更适合表示赋值。

    2013 年 12 月 28 日 下午 1:39

  21. Alex

    我很高兴他们朝着这个方向发展,这已经迟了。我希望语法更优雅。

    2013 年 12 月 30 日 上午 6:59

本文的评论已关闭。