巧妙地制作背景色渐变动画

开发 前端
通过本文,你能了解到 4 种不一样的,使用纯 CSS 制作的渐变背景的过渡动画的方式。

[[393447]]

 通过本文,你能了解到 4 种不一样的,使用纯 CSS 制作的渐变背景的过渡动画的方式。

有的时候,我们可能需要下面这样的动画效果,渐变背景色的过渡动画:

渐变背景的过渡动画

假设我们渐变的写法如下:

  1. div { 
  2.     background: linear-gradient(90deg,  #ffc700 0%, #e91e1e 100%); 

按照常规想法,配合 animation ,我们首先会想到在 animation 的步骤中通过改变颜色实现颜色渐变动画,那么我们的 CSS 代码可能是:

  1. div { 
  2.     background: linear-gradient(90deg,  #ffc700 0%, #e91e1e 100%); 
  3.     animation: gradientChange 2s infinite; 
  4.  
  5. @keyframes gradientChange  { 
  6.     100% { 
  7.         // 渐变中的颜色发生了变化 
  8.         background: linear-gradient(90deg,  #e91e1e 0%, #6f27b0 100%); 
  9.     } 

上面我们用到了三种颜色:

  • #ffc700 黄色
  • #e91e1e 红色
  • #6f27b0 紫色

最后,并没有我们预期的结果,而是这样的:

 å›¾ç‰‡

CodePen Demo - linear-graident 变换的动画效果[1]

我们预期的过渡动画,变成了逐帧动画。

也就是说,线性渐变是不支持动画 animation 的。

那单纯的由一个颜色,变化到另外一个颜色呢?像下面这样:

  1. div { 
  2.     background: #ffc700; 
  3.     animation: gradientChange 3s infinite alternate; 
  4.  
  5. @keyframes gradientChange  { 
  6.     100% { 
  7.         background: #e91e1e; 
  8.     } 

我们发现,单纯的单色值之间的变化是可以发生渐变的:

 å›¾ç‰‡

单色渐变

部分属性是不支持直接整个进行过渡动画的

总结一下,线性渐变(径向渐变、角向渐变)是不支持 animation 的,单色的 background 是支持的。

 

查找了下文档,在 background 附近区域截图如下:

哪些 CSS 属性可以动画?[2],上面的截图是不完整的支持 CSS 动画的属性,完整的可以戳左边。

对于 background 相关的,文档里写的是支持 background 但是没有细说不支持 background: linear-gradient()/radial-gradient() 。

那么是否我们想要的背景色渐变动画就无法实现了呢?下面我们就发散下思维看看有没有其他方式可以达到我们的目标。

通过 background-position 模拟渐变动画

上面哪些 CSS 属性可以动画的截图中,列出了与 background 相关还有 background-position,也就是 background-position 是支持动画的,通过改变 background-position 的方式,可以实现渐变动画:

  1. div { 
  2.     background: linear-gradient(90deg,  #ffc700 0%, #e91e1e 50%, #6f27b0 100%); 
  3.     background-size: 200% 100%; 
  4.     background-position: 0 0; 
  5.     animation: bgposition 2s infinite linear alternate; 
  6.  
  7. @keyframes bgposition { 
  8.     0% { 
  9.         background-position: 0 0; 
  10.     } 
  11.     100% { 
  12.         background-position: 100% 0; 
  13.     } 

这里我们还配合了 background-size。首先了解下:

  • background-position:指定图片的初始位置。这个初始位置是相对于以 background-origin 定义的背景位置图层来说的。
  • background-size:设置背景图片大小。当取值为百分比时,表示指定背景图片相对背景区的百分比大小。当设置两个参数时,第一个值指定图片的宽度,第二个值指定图片的高度。

通过 background-size: 200% 100% 将图片的宽度设置为两倍背景区的宽度,再通过改变 background-position 的 x 轴初始位置来移动图片,由于背景图设置的大小是背景区的两倍,所以 background-position 的移动是由 0 0 -> 100% 0 。

通过 background-size 模拟渐变动画

既然 background-position 可以,那么另一个 background-size 当然也是不遑多让。与上面的方法类似,只是这次 background-position 辅助 background-size ,CSS 代码如下:

  1. div { 
  2.     background: linear-gradient(90deg,  #ffc700 0%, #e91e1e 33%, #6f27b0 66%, #00ff88 100%); 
  3.     background-position: 100% 0; 
  4.     animation: bgSize 5s infinite ease-in-out alternate; 
  5.  
  6.  
  7. @keyframes bgSize { 
  8.     0% { 
  9.         background-size: 300% 100%; 
  10.     } 
  11.     100% { 
  12.         background-size: 100% 100%; 
  13.     } 

CodePen--Demo--position-size 实现渐变动画[3]

通过改变 background-size 的第一个值,我将背景图的大小由 3 倍背景区大小向 1 倍背景区大小过渡,在背景图变换的过程中,就有了一种动画的效果。

而至于为什么要配合 background-position: 100% 0 。是由于如果不设置 background-position ,默认情况下的值为 0% 0%,会导致动画最左侧的颜色不变,像下面这样,不大自然:

 å›¾ç‰‡

通过 transform 模拟渐变动画

上面两种方式虽然都可以实现,但是总感觉不够自由,或者随机性不够大。

不仅如此,上述两种方式,由于使用了 background-position 和 background-size,并且在渐变中改变这两个属性,导致页面不断地进行大量的重绘(repaint),对页面性能消耗非常严重,所以我们还可以试试 transfrom 的方法:

下面这种方式,使用伪元素配合 transform 进行渐变动画,通过元素的伪元素 before 或者 after ,在元素内部画出一个大背景,再通过 transform 对伪元素进行变换:

  1. div { 
  2.     position: relative
  3.     overflow: hidden; 
  4.     width: 100px; 
  5.     height: 100px; 
  6.     margin: 100px auto; 
  7.     border: 2px solid #000; 
  8.      
  9.     &::before { 
  10.         content: ""
  11.         position: absolute
  12.         top: -100%; 
  13.         left: -100%; 
  14.         bottom: -100%; 
  15.         right: -100%; 
  16.         background: linear-gradient(45deg,  #ffc700 0%, #e91e1e 50%, #6f27b0 100%); 
  17.         background-size: 100% 100%; 
  18.         animation: bgposition 5s infinite linear alternate; 
  19.         z-index: -1; 
  20.     } 
  21.  
  22.  
  23. @keyframes bgposition { 
  24.     0% { 
  25.         transform: translate(30%, 30%); 
  26.     } 
  27.     25% { 
  28.         transform: translate(30%, -30%); 
  29.     } 
  30.     50% { 
  31.         transform: translate(-30%, -30%); 
  32.     } 
  33.     75% { 
  34.         transform: translate(-30%, 30%); 
  35.     } 
  36.     100% { 
  37.         transform: translate(30%, 30%); 
  38.     } 

实现原理如下图所示:

 å›¾ç‰‡

CodePen--Demo--伪元素配合transform实现背景渐变[4]

上面列出来的只是部分方法,理论而言,伪元素配合能够产生位移或者形变的属性都可以完成上面的效果。我们甚至可以运用不同的缓动函数或者借鉴蝉原则,制作出随机性十分强的效果。

当然,本文罗列出来的都是纯 CSS 方法,使用 SVG 或者 Canvas 同样可以制作出来,而且性能更佳。感兴趣的读者可以自行往下研究。

通过滤镜 hue-rotate 实现渐变动画(更新于2019/04/06)

下面这个方法,可谓是新时代的利器。

通过滤镜 hue-rotate,可以非常方便的实现背景色渐变动画,过渡效果也非常的自然,代码量也少,可以称得上是黑科技了:

  1. div { 
  2.     background: linear-gradient(45deg, #ffc107, deeppink, #9c27b0); 
  3.     animation: hueRotate 10s infinite alternate; 
  4.  
  5. @keyframes hueRotate { 
  6.     0 { 
  7.         filter: hue-rotate(0); 
  8.     } 
  9.     100% { 
  10.         filter: hue-rotate(360deg); 
  11.     } 

  å›¾ç‰‡

CodePen Demo -- hue-rotate实现渐变背景动画[5]

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

到今天(2021/04/15),我们还可以使用 CSS @property 实现背景色渐变动画,它的出现,极大的增强的 CSS 的能力!

根据 MDN -- CSS Property[6],@property CSS at-rule 是 CSS Houdini API 的一部分, 它允许开发者显式地定义他们的 CSS 自定义属性,允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。

  1. @property --colorA { 
  2.   syntax: '<color>'
  3.   inherits: false
  4.   initial-value: fuchsia; 
  5. @property --colorC { 
  6.   syntax: '<color>'
  7.   inherits: false
  8.   initial-value: #f79188; 
  9. @property --colorF { 
  10.   syntax: '<color>'
  11.   inherits: false
  12.   initial-value: red; 
  13. div { 
  14.     background: linear-gradient(45deg, 
  15.         var(--colorA), 
  16.         var(--colorC), 
  17.         var(--colorF)); 
  18.     animation: change 10s infinite linear; 
  19.  
  20. @keyframes change { 
  21.     20% { 
  22.         --colorA: red; 
  23.         --colorC: #a93ee0; 
  24.         --colorF: fuchsia; 
  25.     } 
  26.     40% { 
  27.         --colorA: #ff3c41; 
  28.         --colorC: #e228a0; 
  29.         --colorF: #2e4c96; 
  30.     } 
  31.     60% { 
  32.         --colorA: orange; 
  33.         --colorC: green; 
  34.         --colorF: teal; 
  35.     } 
  36.     80% { 
  37.         --colorA: #ae63e4; 
  38.         --colorC: #0ebeff; 
  39.         --colorF: #efc371; 
  40.     } 

看看效果,完美:

使用 CSS @property 实现的渐变背景动画

简单解读下,CSS @property 其实就是灵活度更高的 CSS 自定义属性,我们也可以称其为 CSS Houdini 自定义属性。其中:

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

在上述的 DEMO 中,我们利用了 CSS Houdini 自定义属性,将原本定义在 background 的过渡效果嫁接到了 color 之上,而 CSS 是支持一个颜色变换到另外一个颜色的,这样,我们巧妙的实现了渐变背景色的过渡动画。

关于更多 CSS @property 相关的内容,你可以戳这篇文章详细了解 -- CSS @property,让不可能变可能[7]

完整的代码可以戳这里:

CodePen Demo -- CSS Houdini 自定义属性实现渐变色过渡动画[8]

至此,我们就得到了 4 种不一样的,使用纯 CSS 制作的渐变背景的过渡动画的方式。

最后

好了,本文到此结束,希望对你有帮助 :)

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS[9] ,持续更新。

参考资料

[1]CodePen Demo - linear-graident 变换的动画效果:

https://codepen.io/Chokcoco/pen/VpXEpz

[2]哪些 CSS 属性可以动画?:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

[3]CodePen--Demo--position-size 实现渐变动画:

https://codepen.io/Chokcoco/pen/KWoYaQ

[4]CodePen--Demo--伪元素配合transform实现背景渐变:

https://codepen.io/Chokcoco/pen/vxRwep

[5]CodePen Demo -- hue-rotate实现渐变背景动画:

https://codepen.io/Chokcoco/pen/MRegJW

[6]MDN -- CSS Property:

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

[7]CSS @property,让不可能变可能:

https://juejin.cn/post/6951201528543707150

[8]CodePen Demo -- CSS Houdini 自定义属性实现渐变色过渡动画:

https://codepen.io/Chokcoco/pen/Bapmzbd

[9]Github -- iCSS:

https://github.com/chokcoco/iCSS

 

责任编辑:姜华 来源: iCSS前端趣闻
相关推荐

2024-01-30 13:53:31

2010-08-11 16:30:49

Flex DataGr

2022-12-26 11:25:25

CSS黑白文字

2010-08-11 16:41:30

Flex DataGr

2021-11-15 07:45:06

CSS 技巧背景光动画

2023-06-07 10:41:43

2015-06-08 11:21:42

iOS技巧

2023-06-05 09:28:32

CSS渐变

2021-05-11 08:19:00

CSS 文字动画技巧

2022-07-12 08:32:17

transition跑马灯

2023-06-30 13:27:54

CSS径向渐变

2013-05-15 10:27:05

R语言

2022-01-07 07:35:28

CSS 技巧磨砂玻璃

2013-06-20 11:10:24

iOS开发UItableView单元格背景渐变

2017-08-29 10:55:15

AEbodymovinhtml

2022-01-16 12:10:18

腾讯动画组件PAG

2024-01-09 08:45:55

前端工具布局系统

2013-06-09 16:26:56

Windows 8.1

2021-05-18 06:22:39

CSS 制作波浪技巧

2024-03-15 08:50:08

CSS3@keyframes动画制作
点赞
收藏

51CTO技术栈公众号