CSS @property,让不可能变可能

发表于 3年以前  | 总阅读数:414 次

本文主要讲讲 CSS 非常新的一个特性,CSS @property,它的出现,极大地增强的 CSS 的能力!根据MDN -- CSS Property[1],@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 自定义属性:

<style>  
@property --property-name {  
  syntax: '<color>';  
  inherits: false;  
  initial-value: #fff;  
}
p {  
  color: var(--property-name);  
}  
</style>  

简单解读下:

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

其中,@property规则中的 syntax 和 inherits 描述符是必需的。当然,在 JavaScript 内定义的写法也很简单,顺便一提:

<script>  
CSS.registerProperty({  
  name: "--property-name",  
  syntax: "<color>",  
  inherits: false,  
  initialValue: "#c0ffee"  
});  
</script>  

支持的 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: '<color#>':接受逗号分隔的颜色值列表

  • syntax: '<length+>':接受以空格分隔的长度值列表

  • syntax: '<length | length+>':接受单个长度或者以空格分隔的长度值列表


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

使用colorsyntax 语法类型作用于渐变

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

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

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

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

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

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

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

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

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

使用 CSS @property 进行改造

OK,接下来我们就是有本文的主角,使用 Houdini API 中的 CSS 自定义属性替换原本的 CSS 自定义属性。简单进行改造一下,使用colorsyntax 语法类型:

@property --houdini-colorA {  
  syntax: '<color>';  
  inherits: false;  
  initial-value: #fff;  
}  
@property --houdini-colorB {  
  syntax: '<color>';  
  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设定过渡动画,再看看这次的效果: Wow,成功了,渐变色的变化从两帧的逐帧动画变成了补间动画,实现了从一个渐变色过渡到另外一个渐变色的效果!而这,都得益于 CSS Houdini 自定义变量的强大能力! CodePen Demo -- CSS Houdini 自定义变量实现渐变色过渡动画[2]

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

在上述的 DEMO 中,我们利用了 CSS Houdini 自定义变量,将原本定义在background的过渡效果嫁接到了color之上,而 CSS 是支持一个颜色变换到另外一个颜色的,这样,我们巧妙的实现了渐变背景色的过渡动画。在之前我们有讨论过在 CSS 中有多少种方式可以实现渐变背景色过渡动画 --巧妙地制作背景色渐变动画![3],到今天,我们又多了一种实现的方式!

@property --colorA {  
  syntax: '<color>';  
  inherits: false;  
  initial-value: fuchsia;  
}  
@property --colorC {  
  syntax: '<color>';  
  inherits: false;  
  initial-value: #f79188;  
}  
@property --colorF {  
  syntax: '<color>';  
  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;  
  }  
}  

完整的代码可以戳这里: CodePen Demo -- CSS Houdini 自定义变量实现渐变色过渡动画2[4]

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

OK,上面我们演示了syntaxcolor语法类型的情况。在文章一开头,我们还列举了非常多的syntax类型。下面我们尝试下其他的类型,使用percentage百分比类型或者angle角度类型,实现一个饼图的 hover 动画。如果我们还是使用传统的写法,利用角向渐变实现不同角度的饼图:

<div></div>  
.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也是不支持过渡动画的,得到的是一帧向另外一帧的直接变化:

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

@property --per {  
  syntax: '<percentage>';  
  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%;  
  }  
}  

看看改造后的效果:

CodePode Demo -- conic-gradient 配合 CSS \@property 实现饼图动画[5]以往使用纯 CSS 非常复杂才能实现的效果,如果可以轻松的达成,不得不感慨CSS @property强大的能力!

syntax 的 | 符号

顺便演示一下定义 Houdini 自定义变量时 syntax 的一些稍微复杂点的用法。在conic-gradient中,我们可以使用百分比也可以使用角度作为关键字,上述的 DEMO 也可以改造成这样:

@property --per {  
  syntax: '<percentage> | <angle>';  
  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不支持过渡动画,得到的结果如下:

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

@property --offset {  
  syntax: '<length>';  
  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;  
  }  
}

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

CodePen Demo - Underlines hover transition\(Chrome solution with Houdini\)[6]

实战一下,使用 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));  
}  

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

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

body,  
html {  
  width: 100%;  
  height: 100%;  
} 
@property --perA {  
  syntax: '<percentage>';  
  inherits: false;  
  initial-value: 75%;  
}
@property --perB {  
  syntax: '<percentage>';  
  inherits: false;  
  initial-value: 99%;  
}
@property --perC {  
  syntax: '<percentage>';  
  inherits: false;  
  initial-value: 15%;  
}
@property --perD {  
  syntax: '<percentage>';  
  inherits: false;  
  initial-value: 16%;  
}
@property --perE {  
  syntax: '<percentage>';  
  inherits: false;  
  initial-value: 86%;  
}
@property --angle {  
  syntax: '<angle>';  
  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 上传大小限制,加快了速率,截取了其中一部分,简单做个示意): 整体的效果还是挺不错的,完整的 Demo 你可以戳这里: CodePen Demo -- CSS \@property PureCSS Wrapper[7]

参考文献:

  • CSS Properties and Values API Level 1[8]

最后

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

参考资料

[1]MDN -- CSS Property: https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property

[2]CodePen Demo: https://codepen.io/Chokcoco/pen/eYgyWLB?editors=1100

[3]巧妙地制作背景色渐变动画: https://github.com/chokcoco/iCSS/issues/10

[4]CodePen Demo: https://codepen.io/Chokcoco/pen/Bapmzbd

[5]undefined: undefined

[6]CodePode Demo: https://codepen.io/Chokcoco/pen/QWdqMvo

[7]CodePen Demo -- CSS @property PureCSS Wrapper: https://codepen.io/Chokcoco/pen/VwPxMBP

[8]CSS Properties and Values API Level 1: https://drafts.css-houdini.org/css-properties-values-api-1/#at-property-rule

[9]Github -- iCSS: https://github.com/chokcoco/iCSS

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/lneJrApkkSKa98hK0Aw9nw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 6年以前  |  237375次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8244次阅读
 目录