无需登录 数据私有 本地保存

@property 规则演示 - 自定义属性类型与动画

5
0
0
0
@property 规则

CSS @property 允许你定义自定义属性的类型,让浏览器知道如何对它们进行平滑插值,从而解锁 CSS 动画的新维度。

MDN 文档
直观对比:有 @property vs 无 @property
@property 已定义

颜色平滑过渡,浏览器在色彩空间中插值

syntax: '<color>'
无 @property

颜色突然跳变,浏览器在关键帧之间离散切换

未注册的自定义属性
动画速度: 1x
<color>
案例 1:颜色动画

背景颜色在蓝紫色和玫红色之间平滑渐变

@property --demo-typed-color { syntax: '<color>'; inherits: false; initial-value: #6366f1; } @keyframes colorPulse { 0%, 100% { --demo-typed-color: #6366f1; } 50% { --demo-typed-color: #ec4899; } } /* 应用:背景色平滑过渡 */ .element { background: var(--demo-typed-color); animation: colorPulse 3s ease-in-out infinite; }
<angle>
案例 2:锥形渐变旋转

conic-gradient 角度平滑旋转,传统 CSS 无法直接动画渐变角度

@property --demo-angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; } @keyframes rotateGradient { to { --demo-angle: 360deg; } } /* 锥形渐变背景随角度旋转 */ .element { background: conic-gradient(from var(--demo-angle), #6366f1, #ec4899, #6366f1); animation: rotateGradient 3s linear infinite; }
<length>
案例 3:长度动画

宽度在 40px 到 280px 之间平滑伸缩

@property --demo-bar-width { syntax: '<length>'; inherits: false; initial-value: 40px; } @keyframes stretchBar { 0%, 100% { --demo-bar-width: 40px; } 50% { --demo-bar-width: 280px; } } /* 使用自定义长度属性驱动宽度 */ .bar { width: var(--demo-bar-width); animation: stretchBar 2.5s ease-in-out infinite; }
<number>
案例 4:数字驱动的缩放

scale 值在 0.6 到 1.4 之间平滑呼吸

@property --demo-scale { syntax: '<number>'; inherits: false; initial-value: 1; } @keyframes breathe { 0%, 100% { --demo-scale: 0.6; } 50% { --demo-scale: 1.4; } } /* 数字属性驱动 transform: scale() */ .element { transform: scale(var(--demo-scale)); animation: breathe 2s ease-in-out infinite; }
<percentage>
案例 5:渐变位置移动

渐变中颜色停止点位置在 10% 到 90% 之间移动

@property --demo-grad-pos { syntax: '<percentage>'; inherits: false; initial-value: 10%; } @keyframes moveGradient { 0%, 100% { --demo-grad-pos: 10%; } 50% { --demo-grad-pos: 90%; } } /* 百分比驱动渐变颜色停止位置 */ .element { background: linear-gradient(90deg, #6366f1 var(--demo-grad-pos), #ec4899); animation: moveGradient 3s ease-in-out infinite; }
组合类型
案例 6:多属性组合动画

同时驱动颜色、长度和角度,构建复杂动画系统

@property --demo-typed-color { syntax: '<color>'; ... } @property --demo-bar-width { syntax: '<length>'; ... } @property --demo-angle { syntax: '<angle>'; ... } /* 单一关键帧同时驱动多个类型化属性 */ @keyframes comboAnim { 0%, 100% { --demo-typed-color: #6366f1; --demo-bar-width: 40px; --demo-angle: 0deg; } 50% { --demo-typed-color: #ec4899; --demo-bar-width: 200px; --demo-angle: 180deg; } }
常见问题与知识点
什么是 CSS @property 规则?

@property 是 CSS Houdini API 的一部分,允许开发者在 CSS 中显式定义自定义属性(CSS 变量)的语法类型、继承行为和初始值。通过为自定义属性指定类型(如 <color><length><angle> 等),浏览器就能在动画中对这些属性进行平滑插值,而不是在关键帧之间离散跳变。它于 2021 年在 Chrome 85+ 中首次支持,现已被所有主流浏览器广泛支持。

@property 与普通 CSS 自定义属性有什么区别?

普通 CSS 自定义属性(如 --my-color: red;)没有类型信息,浏览器将其值视为通用字符串。在动画中,浏览器无法对字符串进行插值计算,只能在关键帧之间离散切换(在动画中点突然跳变)。而 @property 定义的属性有明确的类型,浏览器知道如何计算中间值——例如颜色会在色彩空间中插值,长度会计算中间像素值,角度会进行数值插值——从而实现真正平滑的过渡动画

@property 支持哪些语法类型(syntax)?

@property 的 syntax 描述符支持以下类型值:
基础类型:<color><length><number><percentage><angle><time><integer><url><image><resolution><transform-function><custom-ident> 等。
组合类型:可以使用 | 表示"或"(如 <number> | <percentage>),使用 + 表示空格分隔的多个值,使用 # 表示逗号分隔的列表。
通用类型:'*' 表示接受任何值(此时行为类似普通自定义属性)。

@property 的三个描述符分别有什么作用?

syntax(必需):定义属性的值类型,用引号包裹,如 '<color>'。这是 @property 最关键的描述符,决定了浏览器如何解析和插值。
inherits(必需):布尔值,指定属性是否从父元素继承。大多数情况下设为 false,配合 initial-value 使用。
initial-value(可选但推荐):属性的初始值。如果 inheritsfalse,则必须提供此值。该值必须符合 syntax 定义的类型。

浏览器兼容性如何?不支持的浏览器会怎样?

@property 在 Chrome 85+、Edge 85+、Opera 71+、Safari 16.4+、Firefox 128+ 中均受支持,覆盖率超过 92%。在不支持的浏览器中,@property 规则会被忽略,自定义属性退化为普通无类型属性,动画将离散切换而非平滑过渡。建议使用 @supports (--css: variables) 进行渐进增强检测,为不支持的环境提供降级方案(如使用传统的 CSS transition 或 JavaScript 动画)。

@property 有哪些实际应用场景?

1. 渐变动画:对渐变的颜色、位置、角度进行平滑动画,实现动态渐变背景。
2. 主题切换:定义颜色类型的属性,在亮/暗主题之间平滑过渡,而非生硬切换。
3. 复杂微交互动效:如按钮 hover 时的渐变色变化、卡片阴影颜色过渡等。
4. 数据可视化:驱动图表元素的尺寸、位置、颜色平滑变化。
5. 创意动画:实现传统 CSS 无法实现的动画效果(如 conic-gradient 旋转)。

@property 定义的属性能否在 JavaScript 中操作?

可以。@property 定义的属性仍然是 CSS 自定义属性,可以通过 element.style.setProperty('--prop-name', value) 在 JavaScript 中设置,也可以使用 getComputedStyle(element).getPropertyValue('--prop-name') 读取。结合 requestAnimationFrame 可以实现高性能的 JavaScript 驱动动画。此外,还可以使用 CSS.registerProperty() 在 JavaScript 中动态注册属性(效果等同于 @property)。

@property 与 CSS transition 能配合使用吗?

可以,而且效果非常好。当自定义属性通过 @property 注册了类型后,CSS transition 也能对该属性进行平滑过渡。例如,使用 transition: --my-color 0.3s ease 就能在属性值变化时产生平滑的颜色过渡。这在主题切换、hover 效果等场景中非常实用——只需改变自定义属性的值,过渡效果自动生效。