使用css的@property规则注册自定义属性结合deepseek完成渐变色融合过渡效果

@property 是一个新特性,支持主流浏览器,它允许开发者显式地定义他们的CSS 自定义属性, 允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承,通过一个简单的案例为大家介绍一下@property规则的用法,详细的介绍文档可以点击链接查看。
https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property

前言

上图是UnoCSS文档内一个比较酷的效果,背景采用了线性渐变,文字和背景的渐变呼应,页面中所有的按钮基于渐变的主色调,效果还是比较酷的,大家感兴趣可以去UnoCSS官方文档查看这个效果。
https://unocss.dev/

这个效果采用的是纯css完成的,结合了animation动画、@keyframes定义关键帧、--css自定义属性、linear-gradient()线性渐变等知识模块。

源码实现起来比较复杂,主要是对@keyframes定义关键帧太过复杂,然后让animation按照这个动画进行轮播,给大家贴一下他的关键帧定义,如果你要是按照他的方法定义,应该会把你给直接劝退。

源码内,关键帧是0%一直定义到100%,每间隔1.25定义一下颜色,如果不配合一些自动化工具或者AI协助,那工作量相当庞大,而且配出来的颜色还不一定好看。

所以我一直尝试,有没有更加渐变的方法实现这个效果,下面是我开发的项目,大家可以微信小程序搜索"鸡汤来喽"小程序,就可以看到我简化后的效果,如图所示:

下面就一步步的给大家介绍,我是如何实现的。

一、自定义属性,AI按需生成关键帧配色

在CSS中通过--标识符定义自定义属性(CSS变量),通过var()函数引用,如下代码示例:

css 复制代码
:root {
  --main-color: #3498db;  /* 定义全局变量 */
}
.element {
  --font-size: 16px;      /* 定义局部变量(仅作用于该元素及其子元素) */
}

.element {
  color: var(--main-color);          /* 直接引用 */
  font-size: var(--font-size, 14px); /* 设置默认值(当变量未定义时生效) */
}

1.给deepseek AI提示词生成css代码(仅作参考)

css 复制代码
@keyframes colorChange {
  0% {
    --color1: 颜色1;
    --color2: 颜色2
  }
}
从0% - 100% 间隔10个为一组,要求color1生成明亮的漂亮的16进制颜色,要求color1的颜色范围广一些能够包含赤橙红绿青蓝紫,
color2根据color1生成邻近色,color2和color1在保持邻近色的同时,
color1和color2邻近色颜色差异调到最大,要求0%和100%能拼接起来,要求100%颜色和0%一样。

最终生成了如下代码,如果想要过渡更好看,可以将关键帧设置的再多一些,这里就生成了10组配色,当然生成之后,不能满足你的需求,你可以简单的进行微调。

css 复制代码
@keyframes colorChange {
  0%, 100% {
    --color1: #ff0000; /* 红色 */
    --color2: #ff8000; /* 橙色 */
  }
  10% {
    --color1: #ff8000; /* 橙色 */
    --color2: #ffff00; /* 黄色 */
  }
  20% {
    --color1: #ffff00; /* 黄色 */
    --color2: #80ff00; /* 黄绿色 */
  }
  30% {
    --color1: #80ff00; /* 黄绿色 */
    --color2: #00ff00; /* 绿色 */
  }
  40% {
    --color1: #00ff00; /* 绿色 */
    --color2: #00ff80; /* 青绿色 */
  }
  50% {
    --color1: #00ff80; /* 青绿色 */
    --color2: #00ffff; /* 青色 */
  }
  60% {
    --color1: #00ffff; /* 青色 */
    --color2: #0080ff; /* 蓝色 */
  }
  70% {
    --color1: #0080ff; /* 蓝色 */
    --color2: #0000ff; /* 深蓝色 */
  }
  80% {
    --color1: #0000ff; /* 深蓝色 */
    --color2: #8000ff; /* 紫色 */
  }
  90% {
    --color1: #8000ff; /* 紫色 */
    --color2: #ff00ff; /* 紫红色 */
  }
}

2.设置animation属性,让动画动起来

css 复制代码
:root{
  --color1: #ff0000;
  --color2: #ffd700;
  --background-gradient: linear-gradient(-45deg, var(--color1), var(--color2));
  animation: colorChange 8s linear infinite;
}
.element{
  width: 300px;
  height: 300px; 
  background: var(--background-gradient);  
}

如上代码:

  1. 给全局:root设置自定义属性--color1和--color2的默认颜色;

  2. 然后设置自定义属性--background-gradient设置线性渐变linear-gradient,线性渐变倾斜45度,第一个颜色是color1,第二个颜色是color2;

  3. 设置animation动画,指定关键帧是上面定义的colorChange,花费8秒钟跑完0%-100%的关键帧,匀速的重复循环播放;

  4. 给要展示的DOM设置背景色,即为刚刚定义的全局属性--background-gradient。

你可以以为这样就实现,可惜效果如下图所示,根本没有颜色融合,而是一帧帧的生硬播放。

这就很奇怪了,如果你使用过animation肯定知道,animation动画是可以对颜色进行融合的,如下图代码演示一下,动画对颜色的融合。

css 复制代码
@keyframes boxColorChange{
  0%{
    background: #ff0000;
  }
  25%{
    background: #8000ff;
  }
  50%{
    background: #00ffff;
  }
  75%{
    background: #00ff00;
  }
  100%{
    background: #0000ff;
  }
}
.box{
  width: 360px;
  height: 360px;
  animation: boxColorChange 8s linear infinite;
}

然后将单色改成线性渐变,测试下过,如下代码所示:

css 复制代码
@keyframes boxColorChange{
  0%{
    background: linear-gradient(#0000ff,#0080ff);
  }
  25%{
    background: linear-gradient(#00ff00,#00ff80)
  }
  50%{
    background: linear-gradient(#ff0000,#ff00ff);
  }
  75%{
    background: linear-gradient(#ff8000,#ffd700);
  }
  100%{
    background: linear-gradient(#ffff00,#00ff80);
  }
}
.box{
  width: 360px;
  height: 360px;
  animation: boxColorChange 8s linear infinite;
}

给背景设置单独颜色,帧动画是可以对颜色融合的,但是设置成渐变色之后将不会融合,知道问题之后就好办了。
第一种方案:

按照UnoCSS定义关键帧的方法,从0%按照递增1.25%的方式手动设置,这种方案显然是费事费力的,即使使用了AI给自动生成,结果需要分三次才能完整生成这个keyframes关键帧。

第二种方案:

使用实验性技术@property,这个规则比较新,但好在目前主流浏览器都支持这种写法。

3.@property注册自定义属性

css 复制代码
@property --property-name {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}

一个有效的 @property 规则代表一项自定义属性的注册,使用自定义属性名作为规则内代码序列的序部。

@property 规则中 syntax 和 inherits 描述符是必需的; 如果其中任何一项缺失,整条规则都将失效并且会被忽略。

initial-value 描述符仅在 syntax 描述符为通用 syntax

定义时是可选的,否则initial-value也是必需的------如果此时该描述符缺失,整条规则都将失效且被忽略。

详情文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property

syntax该属性所允许的语法结构

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

inherits自定义属性注册是否默认继承

true

该属性默认继承。

false

该属性默认不继承。

initial-value为属性设置初始值

initial-value: #c0ffee;

通过上面对@property规则的说明,可以将我们定义的自定义属性--color1和--color2增加@property规则,代码如下:

css 复制代码
@property --color1 {
  syntax: "<color>";
  inherits: true;
  initial-value: #ff0000;
}

@property --color2 {
  syntax: "<color>";
  inherits: true;
  initial-value: #ffd700;
}

然后,可以设置当前元素的模糊度,还可以给文本设置同样的渐变要过,如果觉得颜色太亮,可以使用filter: brightness(70%)滤镜,压一下暗色,给p标签制定单一的颜色--color1,最终的效果及完整的源码如下:

css 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="container">
      <div class="element"></div>
      <img src="https://cdn.qingnian8.com/project/chicken/chicken_color.png" class="logo">
      <h1>@property自定义属性规则</h1>
      <p>有趣的css专题-咸虾米</p>
    </div>    
</body>
</html>
<style>
@keyframes colorChange {
  0%, 100% {
    --color1: #ff0000; /* 红色 */
    --color2: #ff8000; /* 橙色 */
  }
  10% {
    --color1: #ff8000; /* 橙色 */
    --color2: #ffff00; /* 黄色 */
  }
  20% {
    --color1: #ffff00; /* 黄色 */
    --color2: #80ff00; /* 黄绿色 */
  }
  30% {
    --color1: #80ff00; /* 黄绿色 */
    --color2: #00ff00; /* 绿色 */
  }
  40% {
    --color1: #00ff00; /* 绿色 */
    --color2: #00ff80; /* 青绿色 */
  }
  50% {
    --color1: #00ff80; /* 青绿色 */
    --color2: #00ffff; /* 青色 */
  }
  60% {
    --color1: #00ffff; /* 青色 */
    --color2: #0080ff; /* 蓝色 */
  }
  70% {
    --color1: #0080ff; /* 蓝色 */
    --color2: #0000ff; /* 深蓝色 */
  }
  80% {
    --color1: #0000ff; /* 深蓝色 */
    --color2: #8000ff; /* 紫色 */
  }
  90% {
    --color1: #8000ff; /* 紫色 */
    --color2: #ff00ff; /* 紫红色 */
  }
}

@property --color1 {
  syntax: "<color>";
  inherits: true;
  initial-value: #ff0000;
}

@property --color2 {
  syntax: "<color>";
  inherits: true;
  initial-value: #ffd700;
}

:root{
  --color1: #ff0000;
  --color2: #ffd700;
  --background-gradient: linear-gradient(-45deg, var(--color1), var(--color2));
  animation: colorChange 20s linear infinite;  
}

.container{
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 60px auto;
  width: fit-content;
  position: relative;
}

.element{
  width: 300px;
  height: 300px; 
  background: var(--background-gradient);
  border-radius: 50%;
  filter: blur(60px);
}
.logo{
  position: absolute;
  width: 150px;
  top:100px;
}
h1{
  margin-top:60px;
  background: var(--background-gradient);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: brightness(70%);
}
p{
  margin:0;
  color:var(--color1);
}
</style>
相关推荐
donecoding7 分钟前
前端AI开发:为什么选择SSE,它与分块传输编码有何不同?axios能处理SSE吗?
前端·人工智能
安_12 分钟前
<style scoped>跟<style>有什么区别
前端·vue
姝然_952713 分钟前
Claude Code 命令完整文档
前端
wjcroom13 分钟前
web版进销存的设计到实现一
前端
无知的前端16 分钟前
Flutter常见问题以及解决方案
前端·flutter·dart
BD_Marathon28 分钟前
Vue3_Vite构建工程化前端项目
前端
武清伯MVP30 分钟前
CSS Grid布局全解析:从基础到实战的二维布局方案
前端·css·grid
xfq35 分钟前
typescript泛型枚举以及NaN传染处理
前端·typescript
ErMao35 分钟前
开始搭建第一个React项目吧~
前端·react.js
Yanni4Night1 小时前
JavaScript打包器大奖赛:谁是构建速度之王? 🚀
前端·javascript