通过@property自定义css属性

发表于 阅读 27

本文主要讲CSS @property,它极大的增强了CSS的能力,让以前实现起来比较麻烦的逻辑可以轻松实现。

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

语法

@property --property-name { syntax: "<color>"; inherits: false; initial-value: #c0ffee; }

其中 syntaxinherits 描述符是必需的,如果其中任何一项缺失,整条规则都将失效并且会被忽略。 initial-value 描述符仅在 syntax 描述符为通用 syntax 定义时是可选的,否则initial-value也是必需的——如果此时该描述符缺失,整条规则都将失效且被忽略。

未知的描述符自身都是无效的,且会被忽略。但是不会造成整条@property规则的失效。

  • syntax: 描述符,描述该属性的语法结构。如下是所有的有效 syntax 字符串
  • inherits: 是否可以继承
  • initial-value: 默认值

syntax 的语法和取值

语法
syntax: "<color>"; /* 接收一个颜色值 */ syntax: "<length> | <percentage>"; /* 接收长度或百分比参数,但是二者之间不进行计算合并 */ syntax: "small | medium | large"; /* 接收这些参数值之一作为自定义标识符 */ syntax: "*"; /* 任何有效字符 */

还可以使用+#|来增强语法的灵活性,比如:

  • <length>+: 表示用空格分割的<length>列表;
  • <color>#: 以逗号分隔的颜色列表
  • <length> | auto: 可以是<length>,也可以是auto值。
  • "foo | <color># | <integer>": 可以接受foo、以逗号分隔的颜色值或者单个数值。
取值
  • <length>: 由一个 <number> 和一个长度单位构成。与所有 CSS 维度一样,单位的字面值与数字之间没有空格。数字为 0 时,长度单位是可选的。
  • <number>: 表示整数或者是带有小数部分的数字
  • <percentage>: 百分比
  • <length-percentage>: 可以是 <length><percentage>
  • <color>: 颜色
  • <image>: CSS 图像;包括简单的静态图像,经常被一个在使用的 URL 引用,动态生成的图像,比如 DOM 树的部分元素样式渐变或者计算样式产生
  • <url>: 可以是绝对 URL、相对 URL、blob URL 或数据 URL
  • <integer>: 整数
  • <angle>: 表示角的大小,单位为度(degrees)、百分度(gradians)、弧度(radians)或圈数(turns)
  • <time>: 以秒(s)或毫秒(ms)为单位的时间
  • <resolution>: 用于描述媒体查询中的 resolution,表示输出设备的像素密度,即分辨率。
  • <transform-function>: 用于对元素的显示做变换。通常,这种变换可以由矩阵表示,并且可以使用每个点上的矩阵乘法来确定所得到的图像。
  • <custom-ident>: 用户自定义字符串标识符
  • <transform-list>: 一个有效的 <transform-function> 列表

示例

上面介绍了一堆,下面看看实际例子。

通过--my-color给元素设置背景色

@property --my-color { syntax: "<color>"; inherits: true; initial-value: #ff0000; } .container { display: inline-block; width: 200px; height: 200px; background-color: var(--my-color); }

上面的例子乍一看跟css变量没什么区别,css变量是不支持渐变的,@property支持渐变,可以用过它来实现很多花活。

@property实现渐变效果

先看看css变量和@property的渐变效果。background使用线性渐变,鼠标hover时改变颜色。

css变量代码:

:root { --colorA1: #fff; --colorB1: #000; } .container1 { display: inline-block; width: 200px; height: 200px; background: linear-gradient(45deg, var(--colorA1), var(--colorB1)); transition: --colorA1 1s, --colorB1; &:hover { --colorA1: #ac78ff; --colorB1: blue; } }

@property代码:

@property --colorA2 { syntax: "<color>"; inherits: true; initial-value: #fff; } @property --colorB2 { syntax: "<color>"; inherits: true; initial-value: #000; } .container2 { display: inline-block; width: 200px; height: 200px; background: linear-gradient(45deg, var(--colorA2), var(--colorB2)); transition: --colorA2 1s, --colorB2; &:hover { --colorA2: #ac78ff; --colorB2: blue; } }

鼠标hover下面的元素可以看出@property有过渡效果,css变量颜色没有过渡。

使用 css @property 实现过渡动画

下面通过定义了一个动画colorChange,设置了不同时间段的颜色。

@property --colorA { syntax: "<color>"; inherits: true; initial-value: #6925ff; } @property --colorB { syntax: "<color>"; inherits: true; initial-value: #ff0000; } @property --colorC { syntax: "<color>"; inherits: true; initial-value: #000; } @keyframes colorChange { 20% { --colorA: #f7f0ff; --colorB: rgba(207, 156, 68, 0.505); --colorC: #5ddd18c1; } 50% { --colorA: #8d4fff; --colorB: rgb(181, 61, 61); --colorC: #5c4242; } 80% { --colorA: #bb9e1b; --colorB: rgb(46, 201, 157); --colorC: #b03291; } } .container { display: inline-block; width: 200px; height: 200px; background: linear-gradient(45deg, var(--colorA), var(--colorB), var(--colorC)); animation: colorChange 3s infinite linear; }

animation: colorChange 3s infinite linear设置每3s循环一次动画。

使用 css @property实现文字下划线动画

以前有些网站上炫酷的超链接动画都是使用各种黑魔法实现,现在可以自定义属性实现了。

@property --offset { syntax: '<length>'; inherits: false; initial-value: 0; } .container { font-size: 20px; display: inline-block; text-decoration: underline; text-underline-offset: var(--offset, 1px); transition: --offset 500ms, ; &:hover { --offset: 10px; color: red; } }

鼠标放到文字上面就可以看到丝滑的动画效果。

参考文档

https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property

相关文章