我们先来看看实现的效果吧



非常的美腻,对吧。这个是纯css,且单标签实现的哦~

先贴完整代码,我们再来看看这个里面究竟有什么可以借鉴的知识点

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单标签!纯CSS实现动态晴阴雨雪</title>
</head> <body>
<div class="weather sunny"></div>
<div class="weather cloudy"></div>
<div class="weather rainy"></div>
<div class="weather snowy"></div>
</body>
<style>
.weather {
position: relative;
display: inline-block;
width: 180px;
height: 240px;
background: #23b7e5;
border-radius: 8px;
}
.sunny:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: #F6D963;
border-radius: 50%;
box-shadow: 0 0 20px #ff0;
z-index: 2;
}
.sunny:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
margin: -45px 0 0 -45px;
width: 90px;
height: 90px;
background: #FFEB3B;
clip-path: polygon(
50% 0%,
65.43% 25%,
93.3% 25%,
78.87% 50%,
93.3% 75%,
64.43% 75%,
50% 100%,
35.57% 75%,
6.7% 75%,
21.13% 50%,
6.7% 25%,
35.57% 25%);
z-index: 1;
animation: sunScale 2s linear infinite;
}
@keyframes sunScale {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 22px -15px 0 6px,
#fff 57px -6px 0 2px,
#fff 87px 4px 0 -4px,
#fff 33px 6px 0 6px,
#fff 61px 6px 0 2px,
#ccc 29px -23px 0 6px,
#ccc 64px -14px 0 2px,
#ccc 94px -4px 0 -4px;
z-index: 2;
}
.cloudy:before {
animation: cloudMove 2s linear infinite;
}
@keyframes cloudMove {
0% {
transform: translate(-50%, -50%);
}
50% {
transform: translate(-50%, -60%);
}
100% {
transform: translate(-50%, -50%);
}
}
.rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: rainDrop 2s linear infinite;
}
@keyframes rainDrop {
0% {
transform: translate(0, 0) rotate(10deg);
}
100% {
transform: translate(-4px, 24px) rotate(10deg);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}
.snowy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: snowDrop 2s linear infinite;
}
@keyframes snowDrop {
0% {
transform: translateY(0);
}
100% {
transform: translateY(25px);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}
</style>
</html>

我们来看看每一部分的方法

一:晴天图标由两个元素组成:太阳和内六角形阳光。

:before、:after 两个伪类可以在元素内部分别“添加”一个元素,正好都利用上了。

绘制太阳

首先,用 :before实现太阳。

.sunny:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: #F6D963;
border-radius: 50%;
box-shadow: 0 0 20px #ff0;
z-index: 2;
}

复制代码content用来生成一个元素。

position、top、left、transform用来实现中心居中。

box-shadow实现外发光效果,这只是box-shadow最基本最常用的使用方式

用 :after实现内六角形。

实现的关键就是使用遮罩。通过clip-path绘制一个内六角形。这就变成了一个简单的初中几何问题。

内六角形由两个等边三角形拼合而成。

使用clip-path的polygon方法绘制内六角形,坐标已通过上面的步骤计算出来了。

.sunny:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
margin: -45px 0 0 -45px;
width: 90px;
height: 90px;
background: #FFEB3B;
clip-path: polygon(
50% 0%,
65.43% 25%,
93.3% 25%,
78.87% 50%,
93.3% 75%,
64.43% 75%,
50% 100%,
35.57% 75%,
6.7% 75%,
21.13% 50%,
6.7% 25%,
35.57% 25%);
z-index: 1;
animation: sunScale 2s linear infinite;
}
@keyframes sunScale {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}

※注:safari需要将clip-path改为-webkit-clip-path。

实现原理就是通过clip-path绘制了一个内六角形遮罩,把黄颜色背景通过遮罩变成了最终的内六角形。

animation通过关键帧动画实现了“放大缩小”交替动效

阴天

观察图形发现,有两个云朵:前面的白云和后面的乌云。貌似需要分别用 :before和 :after实现。如果这样做的话,后续章节的雨天和雪天的雨雪元素就没有多余的伪类可用了。所以只能用一个伪类实现两朵云。 这里就用到了box-shadow的“影分身”了!

由于后续章节的雨天和雪天都复用了云的样式,所以写在一起了,代码如下:

.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
z-index: 2;
}

真实的元素(真身)就是一个圆。通过box-shodow来把投影作为“分身”。

先来看看box-shadow的属性:

box-shadow: h-shadow v-shadow blur spread color inset;

参数详解:

h-shadow: 阴影的水平偏移量。

v-shadow: 阴影的垂直偏移量。

blur: 模糊距离(就是渐变的距离,设为0就没有渐变)。

spread: 投影的尺寸,通过这个控制“影分身”的大小。

color: 投影颜色,通过这个实现后方的乌云。

inset: 改为内阴影。这里用不到。

复制多个影分身,带全部影分身的完整代码如下:

.cloudy:before,
.rainy:before,
.snowy:before {
content: "";
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 22px -15px 0 6px,
#fff 57px -6px 0 2px,
#fff 87px 4px 0 -4px,
#fff 33px 6px 0 6px,
#fff 61px 6px 0 2px,
#ccc 29px -23px 0 6px,
#ccc 64px -14px 0 2px,
#ccc 94px -4px 0 -4px;
z-index: 2;
}

五个分身的白圆(#fff),三个分身的灰圆(#ccc)拼成了两朵云。

再给云朵加上“上下浮动”的动效:

.cloudy:before {
animation: cloudMove 2s linear infinite;
}
@keyframes cloudMove {
0% {
transform: translate(-50%, -50%);
}
50% {
transform: translate(-50%, -60%);
}
100% {
transform: translate(-50%, -50%);
}
}

雨天

云朵的代码直接复用第4章的阴天。这里使用 :after 伪类实现雨滴。

先实现一个雨滴(为方便观看,暂时隐藏云朵):

.rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
}

然后通过box-shadow“影分身”:

    .rainy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 4px;
height: 14px;
background: #fff;
border-radius: 2px;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
}

再加入下雨的移动动效,修改如下:

    .rainy:after {
...(略)
animation: rainDrop 2s linear infinite;
}
@keyframes rainDrop {
0% {
transform: translate(0, 0) rotate(10deg);
}
100% {
transform: translate(-4px, 24px) rotate(10deg);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}

动画添加了10度的旋转,让雨滴倾斜,以及垂直方向的移动。

这里的关键就是:虽然本质是垂直移动,但为了看上去是“循环”效果,需要将最下面的雨滴进行透明渐变,同时调节X和Y轴的值,让最终位置正好跟初始位置重合,就不会显得“断开”。

我们生成的是三行雨滴,第一行被云朵挡住了,实际能看到的是下面两行。在第一行移动到第二行位置的时候,原第三行已经透明看不见了,正好与初始状态一样,实现了无缝循环拼接。

雪天与雨天的区别就是把雨滴换成圆形,取消旋转角度。 代码如下:

.snowy:after {
content: "";
position: absolute;
top:50%;
left: 25%;
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
#fff 0 50px 0,
#fff 25px 40px 0,
#fff 50px 50px 0,
#fff 75px 40px 0;
animation: snowDrop 2s linear infinite;
}
@keyframes snowDrop {
0% {
transform: translateY(0);
}
100% {
transform: translateY(25px);
box-shadow:
#fff 25px -10px 0,
#fff 50px 0 0,
#fff 75px -10px 0,
#fff 0 25px 0,
#fff 25px 15px 0,
#fff 50px 25px 0,
#fff 75px 15px 0,
rgba(255, 255, 255, 0) 0 50px 0,
rgba(255, 255, 255, 0) 25px 40px 0,
rgba(255, 255, 255, 0) 50px 50px 0,
rgba(255, 255, 255, 0) 75px 40px 0;
}
}

本文转载自:https://juejin.im/post/5d2716ab5188257b775d35ba

有趣的纯CSS实现动态晴阴雨雪的更多相关文章

  1. 谈谈一些有趣的CSS题目(八)-- 纯CSS的导航栏Tab切换方案

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  2. 谈谈一些有趣的CSS题目(十四)-- 纯 CSS 方式实现 CSS 动画的暂停与播放!

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  3. 纯CSS无hacks的跨游览器多列布局

    利用纯CSS创建一个等高多列的布局并不件易事,本教程将着重分析出现在多列布局的多个问题,然后为大家等来一个简单全游览器通吃的解决方法,不使用图片,脚本,CSS hacks并在最严格的XHTML 规范中 ...

  4. 超强的纯 CSS 鼠标点击拖拽效果

    背景 鼠标拖拽元素移动,算是一个稍微有点点复杂的交互. 而在本文,我们就将打破常规,向大家介绍一种超强的仅仅使用纯 CSS 就能够实现的鼠标点击拖拽效果. 在之前的这篇文章中 -- 不可思议的纯 CS ...

  5. 纯CSS3实现动态火车行驶特效

    上次开完飞机,这次开火车 查看效果:http://hovertree.com/texiao/css3/7/ 效果图: 代码如下: <!DOCTYPE html> <html> ...

  6. CSS布局技巧 -- 纯CSS让子元素的宽度总和决定其父元素的宽度

    使用场景 在移动端屏幕宽度有限的前提下,使用横向滚动的方式展示更多的内容.在这样的需求下,希望父元素作为容器,其宽度可以又横向排列资源的总宽度动态撑开,超过祖父元素的宽度:在不超过祖父元素时,自动继承 ...

  7. 纯CSS滑动效果

    原文地址:Pure CSS Slide Up and Slide Down 示例地址:Pure CSS Slide Demo 原文日期: 2013年08月26日 翻译日期: 2013年08月27日 如 ...

  8. 纯 CSS 实现波浪效果!

    一直以来,使用纯 CSS 实现波浪效果都是十分困难的. 因为实现波浪的曲线需要借助贝塞尔曲线. 而使用纯 CSS 的方式,实现贝塞尔曲线,额,暂时是没有很好的方法. 当然,借助其他力量(SVG.CAN ...

  9. 分享:纯 css 瀑布流 和 js 瀑布流

    分享一次纯 css 瀑布流  和 js 瀑布流 纯 css 写瀑布流 1.multi-columns 方式: 通过 Multi-columns 相关的属性 column-count.column-ga ...

随机推荐

  1. sql server2014显示sa无法登录的错误

    博主用的是sql serser2014,不过这个问题的方法也适用于2012等其他版本. 当用sa登录的时候,提示如下错误: A connection was successfully establis ...

  2. 13-8-return的高级使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. java 压缩包

    package com.gome.budget.common.utils; import org.apache.commons.compress.archivers.ArchiveEntry; imp ...

  4. Android开发 设备横屏与竖屏的详解

    需要了解横竖屏切换关键知识 1.在Android设备的横竖屏幕,每一次切换横竖屏其实是在重新创建Activity,Activity会重新走一遍生命周期.从onCreate 到 onDestroy 2. ...

  5. 【SDOI2015】约数个数和

    题面 求\(\sum_{i=1}^n\sum_{j=1}^md(ij)\) \(\leq 50000\)组数据,\(1\leq n,m\leq 50000\). 题目分析 首先,你需要知道一个结论: ...

  6. 安装tomcat8.5

    1.去官网下载安装文件 网址:https://tomcat.apache.org/download-80.cgi 2.在安装目录的bin中运行startup.bat即可启动 3.启动好tomcat后, ...

  7. CodeForces - 27E

    https://vjudge.net/problem/CodeForces-27E 求因子个数为n的最小的数dfs枚举质因子的幂 #include <iostream> #include ...

  8. 高斯消元+期望dp——light1151

    高斯消元弄了半天没弄对.. #include<bits/stdc++.h> using namespace std; #define maxn 205 #define eps 1e-8 d ...

  9. 你知道的和不知道的sass

    关于sass,大多数人的认识一个写css的工具而已 其实就是的 但是这个工具的威力你发挥了多少呢... 以下全部都是干货,希望你能用在自己的项目里 定义集合 我们通常是这么定义变量的 $warning ...

  10. CPU中的主要的寄存器

    寄存器 名为寄存器的存储电路. 8种16位寄存器 AX accumulator 累加寄存器 CX counter 计数寄存器 DX data 数据寄存器 BX base 基址寄存器 SP stack ...