探索 CSS @property:开启灵活样式的新篇章!

什么是 CSS @property?

CSS @property 是 CSS 的一个新特性,允许开发者定义自定义属性(或称为 CSS 变量),并为这些属性指定默认值、类型和继承规则。这使得 CSS 的可扩展性和可维护性得到了显著提升。

主要特性

  1. 自定义属性定义

    • 使用 @property 语法定义自定义属性。
  2. 类型支持

    • 支持不同的数据类型。
      • length
      • number
      • percentage
      • length-percentage
      • color
      • image
      • url
      • integer
      • angle
      • time
      • resolution
      • transform-list
      • transform-function
      • custom-ident (a custom identifier string)
  3. 继承和默认值

    • 可以为属性设置默认值和继承规则。

语法

css

vbnet 复制代码
@property --my-custom-property {
  syntax: '<length>';
  inherits: false;
  initial-value: 10px;
}
  • syntax:定义属性的值类型。
  • inherits:指定属性是否可继承。
  • initial-value:定义属性的初始值。

js

使用 JavaScript 中的CSS.registerProperty函数:

js 复制代码
window.CSS.registerProperty({
  name: "--my-custom-property",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee",
});
  • name: css自定义属性名称
  • syntax:定义属性的值类型。
  • inherits:指定属性是否可继承。
  • initial-value:定义属性的初始值。

示例

css 复制代码
css
复制
@property --main-color {
  syntax: '<color>';
  inherits: false;
  initial-value: red;
}

div {
  background-color: var(--main-color);
}

div:hover {
  --main-color: blue; /* Hover 时改变颜色 */
}

有趣的 CSS @property 应用示例

1. 动态背景色渐变

使用 @property 实现一个动态背景色渐变效果,用户在鼠标悬停时,背景色将平滑过渡。

css 复制代码
@property --bg-color0 {
  syntax: '<color>';
  inherits: false;
  initial-value: rgb(135, 89, 215);
}

@property --bg-color1 {
  syntax: '<color>';
  inherits: false;
  initial-value: rgb(34, 222, 237);
}


.dynamic-bg {
  width: 100%;
  height: 100vh;
  background: linear-gradient(var(--bg-color0), var(--bg-color1));
  transition: --bg-color0 1s, --bg-color1 1s;
}

.dynamic-bg:hover {
  --bg-color0: rgb(77, 243, 119);
  --bg-color1: rgb(73, 164, 238);
}

2.饼图动画

less 复制代码
@property --transparentFrom {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 25%;
}

.container {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: conic-gradient(
    yellowgreen,
    yellowgreen var(--transparentFrom),
    transparent var(--transparentFrom),
    transparent 100%
  );
  transition: --transparentFrom 300ms;

  &:hover {
    --transparentFrom: 50%;
  }
}

3.网页动态背景动画

css 复制代码
  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;
      }
    }

4. 图片渐隐消失动画

scss 复制代码
$count: 400;
$sqrt: 20;
$per: 100% / $sqrt;
$width: 300px;
$perWid: 15;

@for $i from 1 to ($count + 1) {
    @property --m-#{$i} {
       syntax: "<number>";
       initial-value: 1;
       inherits: false;
    }
}
@function bgSet($n) {
    $bg : radial-gradient(rgba(0, 0, 0, var(--m-1)), rgba(0, 0, 0, var(--m-1)));
    
    @for $i from 2 through $n {         
        $bg: $bg, radial-gradient(rgba(0, 0, 0, var(--m-#{$i})), rgba(0, 0, 0, var(--m-#{$i})));
    }
    
    @return $bg;
}
@function positionSet($n) {
    $bgPosition: ();

    @for $i from 0 through ($n) {   
        @for $j from 0 through ($n - 1) {  
            $bgPosition: $bgPosition, #{$i * $perWid}px #{$j * $perWid}px;
        }
    }
    
    @return $bgPosition;
}
@function transitionSet($n) {
    $transition: --m-1 0.1s 0.1s;

    @for $i from 1 through $n {   
        $transition: $transition, --m-#{$i} #{random(500)}ms #{random(500)}ms;
    }
    
    @return $transition;
}
div {
    width: $width;
    height: $width;
    background: url(image.jpg);
    mask: bgSet($count);
    mask-size: $per $per;
    mask-repeat: no-repeat;
    mask-position: positionSet($sqrt); 
    transition: transitionSet($count);
    img{
      width: 100%;
    }
}
div:hover {
    @for $i from 1 through $count {         
        --m-#{$i}: 0;
    }
}

浏览器支持

目前,CSS @property 在现代浏览器中逐渐得到支持,但仍需检查兼容性。可以参考 Can I use 网站获取最新信息。

参考文献

  1. Houdini MDN
  2. @property MDN
  3. iCSS - css@property
  4. 现代 CSS 之高阶图片渐隐消失术 - ChokCoco - 博客园
相关推荐
qq. 28040339842 小时前
CSS层叠顺序
前端·css
喝拿铁写前端2 小时前
SmartField AI:让每个字段都找到归属!
前端·算法
猫猫不是喵喵.2 小时前
vue 路由
前端·javascript·vue.js
烛阴3 小时前
JavaScript Import/Export:告别混乱,拥抱模块化!
前端·javascript
bin91533 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例12,TableView16_12 拖拽动画示例
前端·javascript·vue.js·ecmascript·deepseek
GISer_Jing3 小时前
[Html]overflow: auto 失效原因,flex 1却未设置min-height &overflow的几个属性以及应用场景
前端·html
程序员黄同学3 小时前
解释 Webpack 中的模块打包机制,如何配置 Webpack 进行项目构建?
前端·webpack·node.js
拉不动的猪3 小时前
vue自定义“权限控制”指令
前端·javascript·vue.js
再学一点就睡3 小时前
浏览器页面渲染机制深度解析:从构建 DOM 到 transform 高效渲染的底层逻辑
前端·css
拉不动的猪4 小时前
刷刷题48 (setState常规问答)
前端·react.js·面试