今天给大家分享一下如何用纯 CSS 绘制一朵美丽的雪花,效果图如下:
定义 DOM 结构、页面背景和容器尺寸,最外层容器是一个名为 .snowflake 的 <figure>
元素,内含 6 个 <div>
元素,分别代表雪花的6个花瓣,每个 <div>
中又包含 5 个 <span>
元素,每个 <span>
代表雪花上的冰凌。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <figure class="snowflake"> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <div> <span></span> <span></span> <span></span> <span></span> <span></span> </div> </figure>
|
页面背景取黑色,雪花取白色,并为容器画出黄色的轮廓作为辅助线,雪花图案将绘制在这个黄色虚线框内:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| body { margin: 0; height: 100vh; display: flex; align-items: center; justify-content: center; background-color: black; overflow: hidden; } .snowflake { font-size: 100px; color: snow; width: 4em; height: 4em; outline: 1px dashed yellow; }
|
绘制出6个花瓣,先绘制出1个花瓣中间的竖线,发现6个花瓣的竖线重叠在一起了,把它们合并到一起,看起来就像只有1条竖线:
1 2 3 4 5 6 7
| div { position: absolute; width: 0.1em; height: 2em; background-color: currentColor; border-radius: 0.05em; }
|
分别旋转每个花瓣,一共6个花瓣,所以各花瓣的旋转角度均相差60度:
1 2 3 4 5 6 7 8 9 10
| div { transform-origin: bottom; transform: rotate(calc((var(--n) - 1)* 60deg)); } div:nth-child(1) {--n: 1;} div:nth-child(2) {--n: 2;} div:nth-child(3) {--n: 3;} div:nth-child(4) {--n: 4;} div:nth-child(5) {--n: 5;} div:nth-child(6) {--n: 6;}
|
绘制花瓣上的冰凌,接下来修饰花瓣,绘制花瓣上的冰凌。先来出顶端的圆点,用 <div>
里的第1个 <span>
元素实现:
1 2 3 4 5 6 7 8 9 10 11
| div { display: flex; flex-direction: column; align-items: center; } div span:nth-child(1) { width: 0.2em; height: 0.2em; background-color: currentColor; border-radius: 50%; }
|
然后增加离圆点最近的折线,用第 2 个 <span>
元素画出,这是用一个正方形4条边框中的2条实现的:
1 2 3 4 5 6 7 8
| div span:nth-child(2) { width: 0.5em; height: 0.5em; border: 0.1em solid; border-width: 0.1em; border-style: none solid solid none; border-radius: 0.05em; }
|
把折线旋转45度,让它的尖部和竖线重合:
1 2 3
| div span:nth-child(2) { transform: rotate(45deg); }
|
增加第2条折线,和上面的代码类似,只是正方形的边长从 0.5em 缩短到 0.4em 了:
1 2 3 4 5 6 7 8 9
| div span:nth-child(3) { width: 0.4em; height: 0.4em; border: 0.1em solid; border-width: 0.1em; border-style: none solid solid none; border-radius: 0.05em; transform: rotate(45deg); }
|
再增加第3条折线:
1 2 3 4 5 6 7 8 9
| div span:nth-child(4) { width: 0.3em; height: 0.3em; border: 0.1em solid; border-width: 0.1em; border-style: none solid solid none; border-radius: 0.05em; transform: rotate(45deg); }
|
再增加第4条折线:
1 2 3 4 5 6 7 8 9
| div span:nth-child(5) { width: 0.3em; height: 0.3em; border: 0.1em solid; border-width: 0.1em; border-style: none solid solid none; border-radius: 0.05em; transform: rotate(45deg); }
|
你已经发现上面 4 条折线的代码有很多重复的,坚决不能忍,来重构吧,把这 4 段代码合并起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| div span:nth-child(2), div span:nth-child(3), div span:nth-child(4), div span:nth-child(5) { width: var(--side-length); height: var(--side-length); border: 0.1em solid; border-width: 0.1em; border-style: none solid solid none; border-radius: 0.05em; transform: rotate(45deg); }
div span:nth-child(2) {--side-length: 0.5em;} div span:nth-child(3) {--side-length: 0.4em;} div span:nth-child(4) {--side-length: 0.3em;} div span:nth-child(5) {--side-length: 0.3em;}
|
最后,让第1条折线离中心稍远点,这样还能让雪花中心更加漂亮:
1 2 3
| div span:nth-child(2) { margin-top: -0.2em; }
|
增加动画效果,动画效果很简单,就是转啊转地,让这片雪花用10秒时间转一圈:
1 2 3 4 5 6 7 8
| .snowflake { animation: round 10s linear infinite; } @keyframes round { to { transform: rotate(1turn); } }
|
最后,别忘了删掉辅助线。
大功告成了!当然你可以在这里看到源码。
(完)
评论加载中