查看原文
其他

现代CSS:纯 CSS 实现飘雪动画效果

小懒 FED实验室 2024-02-12
关注下方公众号,获取更多现代CSS系列文章

今天北京也飘雪 ❄️ 了!在日常 Web 开发中实现飘雪效果时,我们首先想到的是通过 JavaScript 来实现。现代 CSS 这么强大,能否直接使用 CSS 来实现呢。经过调研后,鉴于现代 CSS 的强大,确实可以使用纯 CSS 来实现飘雪动画效果。

1.核心知识

CSS 关键帧和动画是实现飘雪动画的关键,使用动画延迟、位置变换可以让视觉感知更为明显。同时让图标独立于布局,可以实现雪花像真正的雪花一样飘动。

主要的雪花实现方案有:

1)HTML 元素:

使用多个 HTML 元素来绘制雪花,这个实现起来比较简单,使用雪花 ICON 或者雪花字符(\2744 或 ❄)来充当雪花,这种实现起来比较简单,看着会比较真实。

2)背景图片:

使用背景图片,即 CSS 的 radial-gradient() 函数来绘制雪花,这个可以实现对每个雪花的样式灵活可控

CSS radial-gradient() 函数创建一个 <image>,用来展示由 原点(渐变中心) 辐射开的颜色渐变。这个方法得到的是一个 CSS数据类型的对象,这是一种特殊的 <image>

基本语法:

radial-gradient[ x [, y] ] [ circle | ellipse ] [ extent-keyword ] at [ position ] , [color-stop [, length | persentage]]+ )

2.实现方案

本文采用 CSS radial-gradient() 来实现雪花,通过 html:5div.snow 来快速创建页面框架:

<!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="snow"></div>
  </body>
</html>

2.1.实现雪花元素

为了效果更真实,同时给 .snow 元素增加了两个伪元素 ::before::after 来增强效果。

.snow,
.snow::before,
.snow::after {
  background-image
  radial-gradient4px 4px at 259px 455px, white 50%, rgba(0000) ), 
  radial-gradient6px 6px at 347px 72px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 345px 235px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient(3px 3px at 152px 121px, white 50%, rgba(0000)), 
  radial-gradient(5px 5px at 408px 540px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 131px 307px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 100px 410px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient(4px 4px at 88px 302px, white 50%, rgba(0000)), 
  radial-gradient(4px 4px at 582px 533px, white 50%, rgba(0000)), 
  radial-gradient5px 5px at 488px 476px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient6px 6px at 20px 470px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient(6px 6px at 303px 513px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 50px 491px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 414px 30px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 287px 589px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient4px 4px at 7px 238px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient(5px 5px at 99px 579px, white 50%, rgba(0000)), 
  radial-gradient(6px 6px at 118px 66px, white 50%, rgba(0000)), 
  radial-gradient(5px 5px at 51px 396px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 101px 21px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient6px 6px at 228px 115px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient(4px 4px at 74px 168px, white 50%, rgba(0000)), 
  radial-gradient3px 3px at 158px 9px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient5px 5px at 338px 147px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient5px 5px at 567px 57px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient5px 5px at 210px 99px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient6px 6px at 338px 556px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient4px 4px at 536px 350px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient3px 3px at 281px 36px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient6px 6px at 139px 151px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient6px 6px at 494px 202px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 594px 262px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 338px 239px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 389px 480px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient4px 4px at 85px 391px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient6px 6px at 271px 181px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient3px 3px at 425px 237px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient3px 3px at 239px 399px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient4px 4px at 387px 592px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 307px 461px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient3px 3px at 458px 142px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient(6px 6px at 593px 136px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 458px 363px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient6px 6px at 74px 549px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient5px 5px at 543px 462px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient4px 4px at 496px 547px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient3px 3px at 239px 523px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient(4px 4px at 216px 249px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 120px 195px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient6px 6px at 130px 551px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient(6px 6px at 328px 533px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 531px 461px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient4px 4px at 58px 311px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient(3px 3px at 139px 296px, white 50%, rgba(0000)), 
  radial-gradient3px 3px at 57px 364px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 576px 512px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient5px 5px at 248px 262px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient6px 6px at 576px 244px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 452px 483px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient6px 6px at 154px 175px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient(3px 3px at 593px 286px, white 50%, rgba(0000)), 
  radial-gradient6px 6px at 255px 543px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient5px 5px at 50px 443px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient5px 5px at 23px 71px, rgba(2552552550.950%rgba(0000) ), 
  radial-gradient3px 3px at 182px 435px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 155px 384px, rgba(2552552550.850%rgba(0000) ), 
  radial-gradient5px 5px at 160px 594px, rgba(2552552550.750%rgba(0000) ), 
  radial-gradient(5px 5px at 213px 144px, white 50%, rgba(0000)), 
  radial-gradient3px 3px at 533px 373px, rgba(2552552550.650%rgba(0000) ), 
  radial-gradient4px 4px at 519px 365px, rgba(2552552550.650%rgba(0000) );
}

2.2.实现动画

通过给伪元素 ::before::after 增加动画延迟、透明度、过滤效果,增加动画效果和层次。

.snow,
.snow::before,
.snow::after {
  animation: snow 3s linear infinite;
}

.snow::before {
  opacity0.4;
  animation-duration6s;
  animation-direction: reverse;
  filterblur(3px);
}

.snow::after {
  opacity0.65;
  animation-duration9s;
  animation-direction: reverse;
  filterblur(1.5px);
}

3.最终效果

大家都在看

  1. 重要通知,尽快迁移至 NPM 淘宝镜像新域名!对于 Web 开发人员,Firefox 做到了!

  2. 再见 Zod,你好 Valibot! 🔥

  3. 屏幕捕捉神器:ScreenToGif!开源白板绘图利器:tldraw!|工具推荐

  4. 下一代电子邮件构建工具:React Email 2.0 正式发布,性能大幅提升!🔥

  5. Tailwind v4 即将发布,编译性能提升7倍!Notion 推出日历服务,时间管理更高效!

  6. 完美平替 Express 和 Koa !这两个框架我推荐 🔥

  7. TypeScript 5.4 带来的新工具类型,非常实用;Rust 全栈开发,未来可期!

  8. 2024 年 Node.js 首次发布,这个特性终于支持了!🔥

继续滑动看下一个

现代CSS:纯 CSS 实现飘雪动画效果

小懒 FED实验室
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存