坚定地使用 CSS Custom Properties

坚定地使用 CSS Custom Properties

好久没译文,最近看到这篇 Getting Hardboiled with CSS Custom Properties。觉得不错,翻译出来给大家。现在 CSS 新特性层出不穷,比如 Flex,CSS Grid 等等,我们是不是也可以按照这个思路使用,而不是借助预处理工具呢?
广告

自定义属性(Custom Properties)是一个很有魅力的 CSS 新特性,现代浏览器广泛 支持。但是遇到那些不支持 CSS Custom Properties 的老掉牙浏览器我们该怎么办?等着这些浏览器死翘翘了再支持,还是使用预处理武装 CSS?又或者强硬起来,对它们一笑了之?

之前借助 LESS 或者 Sass 这样预处理工具在样式中使用变量,而今Custom Properties 在 CSS 实现变量的原生支持。

如何使用自定义属性?其实很简单,在样式规则钱添加 -- 即可:

--color-text-default: black;

偏爱用下划线?下面这样也没问题:

--color_text_default: black;

在属性名称中,横线和下划线都可以使用,作死使用空格是不行的。

自定义属性名大小写敏感,--color-text-default--Color-Text-Default 是不一样的哦。

使用 var() 函数可以获取到自定属性的值,这样就可以在样式规则中使用自定义属性。如下例,浏览器获取 --color-text-default 的值 black,应用到 body 元素上。

body {
    color: var(--color-text-default);
}

与 LESS 或者 Sass 中的变量一样,CSS Custom Properties 可以避免重复地在样式表中编写颜色、字体或者尺寸等样式;不过除了这些 CSS Custom Properties 还有更多的特点,级联——可以根据平台的不同,通过 media query 查询来修改;更厉害的是, JavaScript 可以修改自定义属性的值。

译注: Custom Properties 本质上是自定义属性,即 CSS 属性前面添加 即是自定义属性;借助 CSS 的 var() 函数,才可以使用这些自定义属性。例如:var(--header-color)。比起预处理器提供的变量特性,自定义属性还有三个特点:层叠/级联,运行时,JavaScript API。

Serg Hospodarets 写了一篇极好的文章介绍 CSS Custom Properties,示例详尽,探索了各种可能用法。

浏览器支持

看到这里你因该会问浏览器支持情况如何?那我们就来看看。最新版的 Chrome、Edge、Firefox、Opera 和 Safari 支持,IE 11 及以前、Opera Mini 情况不容乐观。

总是这样对不对?

不过别担心,可以使用 @support 指令来检查浏览器是否支持自定义属性:

--color-text-default: black;

body {
    color: black;
}

@supports((--foo: bar)) {
    body {
        color: var(--color-text-default);
    }
}

在 Demo 中,一开始把 body 文本颜色设置为黑色,后面如果浏览器支持我们伪造的 foo 变量,则用一个自定义属性值覆盖之。

默认替代

如果使用的变量未定义会怎么样?没有问题,浏览器会忽略这一条规则。如果你想确保万无一失,可以使用替代指定一个备选值。

body {
    color: var(--color-text-default, black);
}

替代与 CSS 中的字体定义有点像,一个使用逗号隔开的列表。如果自定义属性没有值,浏览器忽略之使用列表中的下一个值。

译注:原文这里的说并不准确。var( <custom-property-name> [, <declaration-value> ]? ),第一个逗号之后的内容都会被当作备选值。例如,var(--foo, red, blue),备选值是 red, blue。参考:CSS Custom Properties for Cascading Variables Module Level 1

预处理器

我们确实可以利用预处理器来把 Custom Properties 转为兼容的 CSS 代码,不过先打住,兄弟。

同样的方式以前是不是也搞过?过去为了使用 CSS3 的那些“高级”特性,比如 border-radius、css columns、Flexbox 等等,我们工程师各种小技巧还少么?问题确实解决了,只是代码写得恶心。

我想还有一种更好的方式——在支持的浏览器中尽情使用 CSS Custom Properties ,为不支持的浏览器提供合适的稍有差别的体验。怎么地?之前我们也这么干过呀!

译注:这种方式被称作“渐进增强”,记得外刊君2012~13年试译了《渐进增强的Web设计》,里面有大量的渐进增强设计的技巧。翻译了挺多章,但于翻译质量被人民邮电出版社给bi了,:)。



两种色调的 Stuff & Nonsense

译注:Stuff & Nonsense 是原作者的站点。

在 IE6 臭名昭著的时代,我为我的站点提供了两套设计

针对那个时代的现代浏览器,网站上到处都是新潮的各种颜色的箭头和靶子。我使用了 CSS 属性选择来实现,当年这可是高级特性:

[class="banner"] {
    background-colour: red;
}

IE6 会忽略那些无法解析的选择器,因此,如果用户用 IE6 访问,会看到一个黑白为主)的站点,这些样式我使用类选择器实现的:

.banner {
    background-colour: black;
}

[class="banner"] {
    background-colour: red;
}



不用说,我这样做大家会觉得我脑子不正常,但是 Microsoft 曾今使用我的网站作为 IE7 支持属性选择器的参考。他们确实做了,就像我说的一样:”做一个更好的浏览器吧!”。

过时浏览器,一边呆着去

好了,这个例子和浏览器不支持 CSS Custom Properties,有什么关系?如何才能利用这些高级特性?不用担心浏览器不支持,不用实现复杂的替代方案,不用花数个小时让替代方案和设计保持一致。

答案就在于 CSS 本身,而且一直如此,浏览器会直接忽略它们不认识的东西。

我们要做的很简单,首先指定一个与设计大相径庭的值,然后在再使用 CSS 自定义属性覆盖之。

body{
    color: black;
    color:var(--color-text-default, black);
}

所有浏览器都懂第一个值(black),如果浏览器足够聪明,懂得 第二个值(var(--color-text-default)),就会覆盖第一个值。过时浏览器不理解就会装作看不到,没效果。这没有问题,更不会死人。

对所有的自定义属性都做这样的处理。为使用过时浏览器的用户提供更简单的替代设计到样式中,就像我在 Stuff & Nonsense 上做的一样。

结论

我相信没人愿意看到网站变坏或者不被别人喜欢——我也不想这样——但是没必要要求在每个浏览器里展示都一致。我们可以为使用过时浏览器的用提供一个设计相对简单的替代方案。

做是否启用新的 CSS 特性的决定时,不要老往技术上考量,有时候可能需要改变一下对所有浏览器都要支持的态度。对老旧浏览器不要心慈手软,接受 CSS Custom Properties 带来的红利,坚定地用起来!

更多资源:

发布于 2017-12-20

文章被以下专栏收录

    关注前端前沿技术,探寻业界深邃思想。https://qianduan.group 欢迎微信/微博搜索『前端外刊评论』,关注我们。欢迎给本专栏投稿,原作译作不限,要求:质量高!如果愿意尝试从事前端技术相关的书籍的编写或翻译工作,请私信外刊君。