0

0

深入了解CSS中的@property特性

青灯夜游

青灯夜游

发布时间:2021-04-20 18:57:51

|

4950人浏览过

|

来源于segmentfault

转载

深入了解CSS中的@property特性

本文主要讲讲 CSS 非常新的一个特性,CSS @property,它的出现,极大的增强的 CSS 的能力!

根据 MDN -- CSS Property,@property CSS at-rule 是 CSS Houdini API 的一部分, 它允许开发者显式地定义他们的 CSS 自定义属性,允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。

CSS Houdini 又是什么呢,CSS Houdini 开放 CSS 的底层 API 给开发者,使得开发者可以通过这套接口自行扩展 CSS,并提供相应的工具允许开发者介入浏览器渲染引擎的样式和布局流程中,使开发人员可以编写浏览器可以解析的 CSS 代码,从而创建新的 CSS 功能。当然,它不是本文的重点,不过多描述。

CSS Property 如何使用呢?我们将通过一些简单的例子快速上手,并且着重介绍它在 CSS 动画中起到的关键性的作用,对 CSS 动画带来的巨大提升。

示例

正常而言,我们定义和使用一个 CSS 自定义属性的方法是这样的:

立即学习前端免费学习笔记(深入)”;

:root {
    --whiteColor: #fff;
}

p {
    color: (--whiteColor);
}

而有了 @property 规则之后,我们还可以像下述代码这样去定义个 CSS 自定义属性:

简单解读下:

  • @property --property-name 中的 --property-name 就是自定义属性的名称,定义后可在 CSS 中通过 var(--property-name) 进行引用
  • syntax:该自定义属性的语法规则,也可以理解为表示定义的自定义属性的类型
  • inherits:是否允许继承
  • initial-value:初始值

其中,@property 规则中的 syntax 和 inherits 描述符是必需的。

当然,在 JavaScript 内定义的写法也很简单,顺便一提:

支持的 syntax 语法类型

syntax 支持的语法类型非常丰富,基本涵盖了所有你能想到的类型。

  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident (a custom identifier string)

syntax 中的 +#| 符号

定义的 CSS @property 变量的 syntax 语法接受一些特殊的类型定义。

  • syntax: '' :接受逗号分隔的颜色值列表
  • syntax: '' :接受以空格分隔的长度值列表
  • syntax: '':接受单个长度或者以空格分隔的长度值列表

OK,铺垫了这么多,那么为什么要使用这么麻烦的语法定义 CSS 自定义属性呢?CSS Houdini 定义的自定义变量的优势在哪里?下面我们一一娓娓道来。

使用 color syntax 语法类型作用于渐变

我们来看这样一个例子,我们有这样一个渐变的图案:

div {
    background: linear-gradient(45deg, #fff, #000);
}

1.png

我们改造下上述代码,改为使用 CSS 自定义属性:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
}

得到的还是同样的一个渐变图:

2.png

我们再加上一个过渡效果:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
    transition: 1s background;
    
    &:hover {
        --colorA: yellowgreen;
        --colorB: deeppink;
    }
}

看看鼠标 Hover 的时候,会发生什么:

3.gif

虽然我们设定了 1s 的过渡动画 transition: 1s background,但是很可惜,CSS 是不支持背景渐变色的直接过渡变化的,我们得到的只是两帧之间的之间变化。

使用 CSS @property 进行改造

OK,接下来我们就是有本文的主角,使用 Houdini API 中的 CSS 自定义属性替换原本的 CSS 自定义属性。

简单进行改造一下,使用 color syntax 语法类型:

@property --houdini-colorA {
  syntax: '';
  inherits: false;
  initial-value: #fff;
}
@property --houdini-colorB {
  syntax: '';
  inherits: false;
  initial-value: #000;
}
.property {
    background: linear-gradient(45deg, var(--houdini-colorA), var(--houdini-colorB));
    transition: 1s --houdini-colorA, 1s --houdini-colorB;
    
    &:hover {
        --houdini-colorA: yellowgreen;
        --houdini-colorB: deeppink;
    }
}

我们使用了 @property 语法,定义了两个 CSS Houdini 自定义变量 --houdini-colorA--houdini-colorB,在 hover  变化的时候,改变这两个颜色。

需要关注的是,我们设定的过渡语句 transition: 1s --houdini-colorA, 1s --houdini-colorB,在这里,我们是针对 CSS Houdini 自定义变量设定过渡,而不是针对 background 设定过渡动画,再看看这次的效果:

4.gif

Wow,成功了,渐变色的变化从两帧的逐帧动画变成了补间动画,实现了从一个渐变色过渡到另外一个渐变色的效果!而这,都得益于 CSS Houdini 自定义变量的强大能力!

CodePen Demo -- CSS Houdini 自定义变量实现渐变色过渡动画

使用 CSS @property 实现渐变背景色过渡动画

在上述的 DEMO 中,我们利用了 CSS Houdini 自定义变量,将原本定义在 background 的过渡效果嫁接到了 color 之上,而 CSS 是支持一个颜色变换到另外一个颜色的,这样,我们巧妙的实现了渐变背景色的过渡动画。

在之前我们有讨论过在 CSS 中有多少种方式可以实现渐变背景色过渡动画 -- 巧妙地制作背景色渐变动画!,到今天,我们又多了一种实现的方式!

@property --colorA {
  syntax: '';
  inherits: false;
  initial-value: fuchsia;
}
@property --colorC {
  syntax: '';
  inherits: false;
  initial-value: #f79188;
}
@property --colorF {
  syntax: '';
  inherits: false;
  initial-value: red;
}
div {
    background: linear-gradient(45deg,
        var(--colorA),
        var(--colorC),
        var(--colorF));
    animation: change 10s infinite linear;
}

@keyframes change {
    20% {
        --colorA: red;
        --colorC: #a93ee0;
        --colorF: fuchsia;
    }
    40% {
        --colorA: #ff3c41;
        --colorC: #e228a0;
        --colorF: #2e4c96;
    }
    60% {
        --colorA: orange;
        --colorC: green;
        --colorF: teal;
    }
    80% {
        --colorA: #ae63e4;
        --colorC: #0ebeff;
        --colorF: #efc371;
    }
}

5.gif

完整的代码可以戳这里:

CodePen Demo -- CSS Houdini 自定义变量实现渐变色过渡动画2

conic-gradient 配合 CSS @property 实现饼图动画

OK,上面我们演示了 syntaxcolor 语法类型的情况。在文章一开头,我们还列举了非常多的 syntax 类型。

WebShop开源网上购物系统
WebShop开源网上购物系统

WebShop网上商店系统专注中小企业、个人的网上购物电子商务解决方案,淘宝商城系统用户/个人首选开店的购物系统!综合5500多用户的意见或建议,从功能上,界面美观上,安全性,易用性上等对网店系统进行了深度的优化,功能更加强大,界面模板可直接后台选择。WebShop网上商店系统特点:1 对于中小企业、个体、个人、店主和淘宝易趣等卖家,可利用WebShop快速建立购物网。2 源代码开放,利用WebS

下载

下面我们尝试下其他的类型,使用 percentage 百分比类型或者 angle 角度类型,实现一个饼图的 hover 动画。

如果我们还是使用传统的写法,利用角向渐变实现不同角度的饼图:

.normal {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: conic-gradient(yellowgreen, yellowgreen 25%, transparent 25%, transparent 100%); 
    transition: background 300ms;
    
    &:hover {
        background: conic-gradient(yellowgreen, yellowgreen 60%, transparent 60.1%, transparent 100%); 
    }
}

将会得到这样一种效果,由于 conic-gradient 也是不支持过渡动画的,得到的是一帧向另外一帧的直接变化:

6.gif

好,使用 CSS Houdini 自定义变量改造一下:

@property --per {
  syntax: '';
  inherits: false;
  initial-value: 25%;
}

div {
    background: conic-gradient(yellowgreen, yellowgreen var(--per), transparent var(--per), transparent 100%); 
    transition: --per 300ms linear;
    
    &:hover {
        --per: 60%;
    }
}

看看改造后的效果:

7.gif

CodePode Demo -- conic-gradient 配合 CSS @property 实现饼图动画

以往使用纯 CSS 非常复杂才能实现的效果,如果可以轻松的达成,不得不感慨 CSS @property 强大的能力!

syntax 的 | 符号

顺便演示一下定义 Houdini 自定义变量时 syntax 的一些稍微复杂点的用法。

conic-gradient 中,我们可以使用百分比也可以使用角度作为关键字,上述的 DEMO 也可以改造成这样:

@property --per {
  syntax: ' | ';
  inherits: false;
  initial-value: 25%;
}
...

表示,我们的自定义属性即可以是一个百分比值,也可以是一个角度值。

除了 | 符号外,还有 +# 号分别表示接受以空格分隔、和以逗号分隔的属性,感兴趣的可以自行尝试。

使用 length 类型作用于一些长度变化

掌握了上述的技巧,我们就可以利用 Houdini 自定义变量的这个能力,去填补修复以前无法直接过渡动画的一些效果了。

过去,我们想实现这样一个文字下划线的 Hover 效果:

p {
    text-underline-offset: 1px;
    text-decoration-line: underline;
    text-decoration-color: #000;
    transition: all .3s;
    
    &:hover {
        text-decoration-color: orange;
        text-underline-offset: 10px;
        color: orange;
    }
}

因为 text-underline-offset 不支持过渡动画,得到的结果如下:

8.gif

使用 Houdini 自定义变量改造,化腐朽为神奇:

@property --offset {
  syntax: '';
  inherits: false;
  initial-value: 0;
}
div {
    text-underline-offset: var(--offset, 1px);
    text-decoration: underline;
    transition: --offset 400ms, text-decoration-color 400ms;
    
    &:hover {
        --offset: 10px;
        color: orange;
    text-decoration-color: orange;
    }
}

可以得到丝滑的过渡效果:

9.gif

CodePen Demo - Underlines hover transition(Chrome solution with Houdini)

实战一下,使用 CSS @property 配合 background 实现屏保动画

嗯,因为 CSS @property 的存在,让以前需要非常多 CSS 代码的工作,一下子变得简单了起来。

我们尝试利用 CSS @property 配合 background,简单的实现一个屏保动画。

我们利用 background 可以简单的得到这样一个图形,代码如下:

html, body {
    width: 100%;
    height: 100%;
}
body {
    background-image:
        radial-gradient(
            circle at 86% 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at 15% 16%,
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at 75% 99%,
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(rgb(34, 222, 237), rgb(135, 89, 215));
}

效果如下,还算可以的静态背景图:

10.png

在往常,我们想让它动起来,其实是需要费一定的功夫的,而现在,通过 CSS @property,对我们希望进行动画的一些元素细节进行改造,可以得到非常不错的动画效果:

body,
html {
    width: 100%;
    height: 100%;
}

@property --perA {
  syntax: '';
  inherits: false;
  initial-value: 75%;
}

@property --perB {
  syntax: '';
  inherits: false;
  initial-value: 99%;
}

@property --perC {
  syntax: '';
  inherits: false;
  initial-value: 15%;
}

@property --perD {
  syntax: '';
  inherits: false;
  initial-value: 16%;
}

@property --perE {
  syntax: '';
  inherits: false;
  initial-value: 86%;
}

@property --angle {
  syntax: '';
  inherits: false;
  initial-value: 0deg;
}

body {
    background-image: 
        radial-gradient(
            circle at var(--perE) 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perC) var(--perD),
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perA) var(--perB),
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(var(--angle), rgb(34, 222, 237), rgb(135, 89, 215));
    animation: move 30s infinite alternate linear;
}

@keyframes move {
    100% {
        --perA: 85%;
        --perB: 49%;
        --perC: 45%;
        --perD: 39%;
        --perE: 70%;
        --angle: 360deg;
    }
}

效果如下(因为 Gif 上传大小限制,加快了速率,截取了其中一部分,简单做个示意):

11.gif

整体的效果还是挺不错的,完整的 Demo 你可以戳这里:

CodePen Demo -- CSS @property PureCSS Wrapper

参考文献:

最后

好了,本文到此结束,介绍了 CSS Houdini API 中的 CSS @property 部分,并且利用它实现了一些以往无法简单实现的动画效果,希望对你有帮助 :)

更多编程相关知识,请访问:编程视频!!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

833

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

744

2023.11.06

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1126

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

192

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1644

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

20

2026.01.19

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

927

2023.09.19

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

CSS教程
CSS教程

共754课时 | 24.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号