CSS Houdini:深入理解CSS自定义属性

特别声明:小站已开通年费VIP通道,年费价格为 ¥365.00元。如果您喜欢小站的内容,可以点击开通会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)

这几天一直在折腾CSS自定义属性,在《图解CSS:CSS自定义属性》和《CSS 自定义属性在Web组件中的应用》都在聊CSS自定义属性。但这个CSS自定义属性和今天要聊和CSS的自定义属性还是有所不同的。他们隶属于两个不同的规范,前者是CSS Custom Properties for Cascading Variables Module Level 1,后者是CSS Properties and Values API Level 1。虽然都是W3C规范中的内容,但还是有较大差异的。而今天要和大家聊的是后者,即CSS Houdini中的CSS自定义属性。

什么是自定义属性

CSS属性和值APICSS Properties and Values API Level 1)是CSS Houdini中规范中的一部分:

允许开发人员创建自己的变量,以便以后在CSS中使用

其主要思想来源于CSS处理器(比如Sass、LESS和Stylus)中的变量特性。在《图解CSS:CSS自定义属性》一文中我们可以得知,CSS处理器中的变量是静态的,只在编译时存在;而CSS自定义属性是动态的,可以在特定的选择器块中修改它们(比如在:hover@media)。除此之外,还可以通过JavaScript读取CSS自定义属性的值和更改CSS自定义属性的值。

如何定义和使用自定义属性

CSS自定义属性的定义和CSS处理器有点类似,也有着自己的标识符:--作为前缀。其名称可以是小写(建议局部使用小写)或大写(建议全局使用大写)。而自定义属性的值可以是我们任何想要的东西,比如字符串数字颜色JavaScript代码。如下面代码所示:

:root {
    --num: 10;
    --string: string;
    --content: 'content';
    --length: 100px;
   --js-prop: if (a > b) return 30; // 这个我在CSS自定义属性中还未看到有实际使用场景
}

CSS自定义属性借助var()函数(一般充当var()函数的参数)可以将CSS自定义属性作为任何CSS属性的值(但有有效值无效值之分),另外,还可以给var()提供一个回退值(fallback),比如没有显式声明CSS自定义属性时,回退值作为var()函数的第二个值传入进去,非常有用。

.class {
    width: calc(var(--num) * 1px);
    height: var(--length);
}

.class:after {
    content: var(--content);
}

如果你担心有没有显式声明CSS自定义属性时,可以在var()中提供一个回退值:

.class {
    margin: var(--margin, 10px);
}

还有一件更重要的事情,即,可以使用CSS自定义属性作为另一个CSS自定义属性的回退值,这种方式也被称为CSS自定义属性的链式调用

.class {
    margin: var(--margin, var(--root-margin, 10px));
}

上面和大家演示的是CSS自定义属性中最基本的使用,除此之外还有其他的一些使用方式,如果你想更深入的了解的话,可以阅读《图解CSS:CSS自定义属性》一文。

CSS自定义属性和自定义变量有什么区别?

实际上,CSS自定义属性和CSS变量之间没有区别,CSS自定义属性被var()调用的时候,它就从CSS自定义属性变成了CSS变量。但CSS中的自定义属和CSS Houdini中的CSS自定义属性在声明的时候有明显的差异,在CSS Houdini中使用CSS.registerProperty来声明一个自定义属性,你还能更好的控制它。因为这样声明的CSS自定义属性,你可以给自定义属性分配CSS类型设置初始值继承

目前仅在Chrome和Firefox中支持registerProperty。如果你想正常使用registerProperty,需要启用“实验性Web平台特性(Experimental Web Platform Features)”。比如在Chrome浏览器中,可以在url中输入:chrome://flags/#enable-experimental-web-platform-features来开启该功能。

如何注册自定义属性?

要注册自定义属性,需要使用CSS.registerProperty方法,并给方法传递一个对象(自定义属性的相关配置)。代码可以像下面这样:

if ('registerProperty' in CSS ) {
    CSS.registerProperty({
        name: '--color',
        syntax: '<color>',
        inherits: true,
        initialValue: 'rgba(0, 0, 0, 1)'
    })
}

首先检测浏览器是否支持注册自定义属性。如果不支持registerProperty,我们仍然可以在样式中使用CSS变量(CSS自定义属性)。而其中的配置对象是必需的。接下来,我们花点时间来看看每个配置参数的作用和意义。

name

nameCSS.registerProperty必须配置的一个参数。如果未配置这个参数,程序将会报错:

试想一下,你本来是想注册一个CSS自定义属性,结果不给他命名,那么怎么称呼这个属性呢?

关于自定义属性命名的另一个要求,那就必须遵循CSS自定义命名的规则,即需要用--标识符开头。这样做的原因,我们能够在CSS处理器中使用CSS自定义属性,并且能和内置的CSS属性区分开来。如果你试图以不正确的命名规则来给CSS自定义属性命名的话:

CSS.registerProperty({
    name: "-color",
    syntax: "<color>",
    inherits: false,
    initialValue: "rgba(0,0,0,1)"
});

程序则会报错:

另外,如果同时注册了两个自定义属性,而且其名称相同时,

CSS.registerProperty({
    name: "--start-color",
    syntax: "<color>",
    inherits: false,
    initialValue: "rgba(0,0,0,1)"
});

CSS.registerProperty({
    name: "--start-color",
    syntax: "<color>",
    inherits: true,
    initialValue: "rgba(0,0,0,0)"
});

浏览器也会报错:

syntax

syntax代表CSS自定义属性的类型定义(Type Definition)。它的默认值是*,类似于TypeScript中的any类型。这意味着可以给属性分配任何值。类型定义的语法很简单,即*<TYPE_NAME>,其中TYPE_NAME应该替换你希望分配给自定义属性的实际CSS类型。在上面看到的示例中,我们给自定义属性分配了一个<color>类型,它允许你分配任何有效的CSS颜色值。例如red#000000rgba(255, 255, 255, 0)hls(240, 20%, 50%)hlsa(35, 5%, 90%, .5)等。

这个其实和CSS规范中的属性有点类似。比如我们就拿color这个属性来举例,它也有<color>这么一项的配置(属性值):

小提示,阅读W3C规范还是有一定的技巧的,如果您感兴趣的话可以阅读《理解 CSS 属性值语法》一文。

在注册CSS自定义属性时,CSS值和单位规范中有许多受支持的语法,简单地说,TYPE_NAME的值有很多种:

TYPE_NAME 描述
<length> 任何有效的长度值,比如pxemvw
<number> 任何有效的数字值
<percentage> 任何有效的
剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/css/css-property-and-value-in-css-houdini.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部