相关文章推荐

CSS自定义属性也被称为CSS变量。这是非常令人兴奋的,因为我们在CSS中终于拥有真正的变量。什么意思,真正的变量?我的意思是可以动态更新和修改变量。虽然CSS处理器有了变量(Sass和PostCSS),这些变量通过编译变成了CSS,但没有动态能力更新其变量。这不是真正的CSS变量,只是用来存储和更新可用的值。

你可以通过 -- 设置CSS变量和通过 var(--varName) 访问已声明的变量。这是一个非常基本的方法,可以像下面声明一个变量和让文本的颜色为 red

div {
    --color: red;
    color: var(--color);

CSS变量是非常令人兴奋的

让我们一起来聊聊,为什么动态的CSS为变量会比以前做得更好。

动态JavaScript+CSS

使用CSS变量,我们现在可以更容易地通过JavaScript更新它的值。这意味着,我们不需要使用内联属性样式或者更新类名。我们可以简单通过替换CSS变量的值。

可以像下面那样给:root传递值:

document.documentElement.style.setProperty('--varName', 'propValue')

这样直接在你的CSS文件中写入或更新:root的值。所以,如果我想更新一个加载条的进度比例时,可以这样做:

function calculateLoadProgress() {
    let loadProgress = 0;
    // codes to update loadProgress here
    return loadProgress;
// Set width of progress bar
document.documentElement.style.setProperty('--progressBarWidth', calculateLoadProgress());

这是众多示例中的一个。@David Khourshid使用React做了一些非常有趣的探索和通过JS库确定值,然后传回给CSS变量。他在最近的CSS Conf EU上做了相关的分享与讨论

动态属性片段

CSS变量有一个很酷的功能需要注意,那就是如何在属性值中指定CSS变量。虽然以前我们单独使用border来声明边框,现在我们可以使用变量更新属性的任何部分,包括缩写的border或者是不知道参数的阴影和渐变属性。

比如这个示例:

.button-gradient {
    background: linear-gradient(var(--gradientAngle), var(--gradientStart),var(--gradientStop));
    --gradientAngle: 60deg;
    --gradientStart: lightpink;
    --gradientStop: lightyellow;
.button-gradient:hover {
    --gradientAngle: 0deg;

在上面的示例中,我们通过提高选择器权重,让后面的属性覆盖前面的属性,但文件体积增大了,我们的代码库也将会被弄乱。但使用CSS变量,我们不需要通过样式覆盖前面的样式,只需要更新CSS的变量。下面是使用CSS变量写的代码:

// Variables
:root {
    --primaryColor: lightgreen;
    --buttonBgColor: var(--primaryColor);
// Base Class
.button {
    background: var(--buttonBgColor);
// Modifier Class
.button--blue {
    --buttonBgColor: lightblue;

使用局部变量我们能做得更好

和上面类似,最新的文档教程案例中CSS变量都是在CSS文件中通过:root来声明变量和变量值。

用来设置全局变量这是一个很好的方式,但不是必需的。CSS变量不仅仅可以在:root中声明,它也可以在CSS文件中的任何时候声明,比如在一个CSS的代码块中指定变量。这类似于JavaScript中使用关键词let来声明变量,可以在{}中声明变量,这种方式声明的变量被称为局部变量。所以我们可以利用这种特性,更好的处理我们的组件样式。

Leveraging CSS Variable scope improves the size, specificity, & semantics of our stylesheets. More...

例如,--buttonBgColor放在:root中作为一个全局变量,并不是我们所需要的东西(比如前面的示例)。较好的做法是在<button>内重命名变量--bgColor。这使它与它的父组件更紧密的耦合在一起,也更具有语义化。

CSS变量的使用规则:除非你需要一个全局变量,否则尽量使用局部CSS变量。然后在你自己需要地方使用。这样可以减少CSS变量在:root中的大量堆积,也使代码更加清晰。

另外一个有趣的就是可以在:root中声明一个默认值,以防他们不存在。var()有另外一个能力,可以接受两个参数,并且可以嵌套在变量中。在下面的示例中,如果没有声明--bgColor,那就Card就会调用--colorPrimary的值,也就是red。所以我们可以删除步骤2的中.button的基本样式和在修饰符中更新--bgColor(如果我们想让默认按钮的颜色是主色)。

// 0. Set global variables here
:root {
    --colorPrimary: red;
.button {
    // 1. Default Styles
    // If --bgColor is not defined, the background will be the fallback: red
    background: var(--bgColor, var(--colorPrimary));
    // 2. Default Values
    // Since --bgColor is defined, the button remains lightgreen
    // If the line below was missing, the button would be red
    --bgColor: lightgreen;
    // ...

如果我们有更复杂的组件,我们仍然可以使用这种技术,并且可以结合像Sass一样的CSS处理器使它更简洁。可以像下面这样的来写按钮,让Card的按钮比主题的基本按钮更大。

.button--large {
    .card & {
        --size: 1.7rem;

我们可以在任何地方更新--size的值,让Card的按钮变得略大一点。使用&技术编译出来的代码:

.card .button--large {
    --size: 1.7rem;

所以我们的结构可以这样写:

<div class="card">
    <button class="button button--pink button--large">
        Large Pink Button
    </button>

让具有红色边框的.card运用上面的代码。我们可以看到有一个更大的紫色按钮:

准备好了?

CSS变量得到了当今浏览器广泛的支持,尽管IE不支持,但Edge也得到了一定的支持。

@supports

在CSS中,我们可以使用@support来检测浏览器是否支持。如果你想玩一些更现代的CSS属性,比如CSS Grid,那么@support是一个很好的工具。你可以像下面那样使用来检测你的浏览器是否支持CSS变量:

@supports(--color: red) {
    // code here implementing variables

使用@support是一个很好的选择,但它也像CSS的变量一样还存在很多争议。所以说,提供一份备用的值,可能是一个更好的解决方案。

传递一份备用值

你可以复用CSS的宽松风格,给同一个属性发送多个值。首先像平时一样写属性值,然后第二写声明的变量:

div {
    --color: red;
    color: red;
    color: var(--color);

这是多余的,但它允许你在一个现有的代码库中慢慢缓解使用一些CSS变量,一旦得到浏览器的支持,使其更容易重构。

CSS变量是超级强大的,并且局部变量使它们成为一个更加强大的工具,能让你模块更干净,更好的模块化设计系统。

  • Demo I Made Sending Using JS to Rewrite CSS Variables Inline
  • Types of CSS Variables, CSS Tricks
  • Using CSS Variables, MDN
  • Why You Should Care About CSS Variables, Rob Dodson
  • Theming With Custom Properties, Harry Roberts
  • Time To Start Using CSS Custom Properties, Serg Hospodarets
  • It’s Time To Start Using CSS Custom Properties
  • CSS Custom Properties and Theming
  • CSS custom properties (native variables) In-Depth
  • CSS @apply rule (native CSS mixins)
  • CSS Variables Are a Bad Idea
  • The power of CSS variables
  • Con­di­tions for CSS Vari­ables
  • CSS Variables — No, really!
  • How to Use CSS Variables for Animation
  • Autoprefixing, with CSS variables!
  • Individualizing CSS Properties with CSS Variables
  • Making Custom Properties (CSS Variables) More Dynamic
  • 本文根据@Una的《Locally Scoped CSS Variables: What, How, and Why》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://una.im/local-css-vars

    大漠

    常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

    如需转载,烦请注明出处:https://www.w3cplus.com/css/local-css-vars.htmlNike Kyrie 5 EP 'UFO'

    常用昵称“大漠”,W3CPlus创始人,曾就职于淘宝。对HTML、CSS和A11Y等领域有一定的认识和丰富的实践经验。现在主要从事智能UI领域的探讨和学习!。CSS和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

    github
     
    推荐文章