昨夜北京下了大雪,让咱们用 CSS 绘制一朵雪花,迎接这洁白美好的世界吧!css
按下右侧的“点击预览”按钮能够在当前页面预览,点击连接能够全屏预览。html
https://codepen.io/comehope/pen/LYEeRBb前端
每日前端实战系列的所有源代码请从 github 下载:git
https://github.com/comehope/front-end-daily-challengesgithub
最外层容器是一个名为 .snowflake
的 <figure>
元素,内含 6 个 <div>
元素,分别表明雪花的6个花瓣,每一个 <div>
中又包含 5 个 <span>
元素,每一个 <span>
表明雪花上的冰凌。ide
<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>
页面背景取黑色,雪花取白色,并为容器画出黄色的轮廓做为辅助线,雪花图案将绘制在这个黄色虚线框内:函数
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; }
效果以下图:布局
先绘制出1个花瓣中间的竖线:flex
div { width: 0.1em; height: 2em; background-color: currentColor; border-radius: 0.05em; }
效果以下图:动画
发现6个花瓣的竖线重叠在一块儿了,把它们合并到一块儿,看起来就像只有1条竖线:
div {
position: absolute;
}
效果以下图:
分别旋转每一个花瓣,一共6个花瓣,因此各花瓣的旋转角度均相差60度:
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>
元素实现:
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条实现的:
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度,让它的尖部和竖线重合:
div span:nth-child(2) { transform: rotate(45deg); }
效果以下图:
增长第2条折线,和上面的代码相似,只是正方形的边长从 0.5em
缩短到 0.4em
了:
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条折线:
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条折线:
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 条折线的代码有不少重复的,坚定不能忍,来重构吧,把这 4 段代码合并起来:
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条折线离中心稍远点,这样还能让雪花中心更加漂亮:
div span:nth-child(2) { margin-top: -0.2em; }
效果以下图:
动画效果很简单,就是转啊转地,让这片雪花用10秒时间转一圈:
.snowflake { animation: round 10s linear infinite; } @keyframes round { to { transform: rotate(1turn); } }
效果以下图:
最后,删除掉辅助助线:
.snowflake { /* outline: 1px dashed yellow; */ }
效果以下图:
大功告成!