用純 CSS 繪制一朵美麗的雪花

問(wèn):如果用css 實(shí)現(xiàn)轉(zhuǎn)動(dòng)的雪花效果
一、動(dòng)態(tài)效果預(yù)覽
復(fù)制跳轉(zhuǎn)下方連接可以去查看動(dòng)態(tài)效果
https://codepen.io/comehope/pen/LYEeRBb
二、源代碼下載
https://github.com/comehope/front-end-daily-challenges
三、代碼解讀
定義 DOM 結(jié)構(gòu)、頁(yè)面背景和容器尺寸
最外層容器是一個(gè)名為 .snowflake 的 <figure> 元素,內(nèi)含 6 個(gè) <div> 元素,分別代表雪花的6個(gè)花瓣,每個(gè) <div> 中又包含 5 個(gè) <span> 元素,每個(gè) <span> 代表雪花上的冰凌。
<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>
頁(yè)面背景取黑色,雪花取白色,并為容器畫(huà)出黃色的輪廓作為輔助線,雪花圖案將繪制在這個(gè)黃色虛線框內(nèi):
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個(gè)花瓣
先繪制出1個(gè)花瓣中間的豎線:
div {
width: 0.1em;
height: 2em;
background-color: currentColor;
border-radius: 0.05em;
}
知識(shí)點(diǎn):currentColor的值即表示color的值
效果如下圖:

發(fā)現(xiàn)6個(gè)花瓣的豎線重疊在一起了,把它們合并到一起,看起來(lái)就像只有1條豎線:
div {
position: absolute;
}
效果如下圖:

分別旋轉(zhuǎn)每個(gè)花瓣,一共6個(gè)花瓣,所以各花瓣的旋轉(zhuǎn)角度均相差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;}
知識(shí)點(diǎn):原來(lái)原生css也可以定義變量 效果如下圖:

繪制花瓣上的冰凌
接下來(lái)修飾花瓣,繪制花瓣上的冰凌。
先來(lái)出頂端的圓點(diǎn),用 <div>里的第1個(gè) <span> 元素實(shí)現(xiàn):
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%;
}
效果如下圖:

然后增加離圓點(diǎn)最近的折線,用第 2 個(gè) <span> 元素畫(huà)出,這是用一個(gè)正方形4條邊框中的2條實(shí)現(xiàn)的:
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;
}
效果如下圖:

把折線旋轉(zhuǎn)45度,讓它的尖部和豎線重合:
div span:nth-child(2) {
transform: rotate(45deg);
}
效果如下圖:

增加第2條折線,和上面的代碼類(lèi)似,只是正方形的邊長(zhǎng)從 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);
}
效果如下圖:

你已經(jīng)發(fā)現(xiàn)上面 4 條折線的代碼有很多重復(fù)的,堅(jiān)決不能忍,來(lái)重構(gòu)吧,把這 4 段代碼合并起來(lái):
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條折線離中心稍遠(yuǎn)點(diǎn),這樣還能讓雪花中心更加漂亮:
div span:nth-child(2) {
margin-top: -0.2em;
}
效果如下圖:

增加動(dòng)畫(huà)效果
動(dòng)畫(huà)效果很簡(jiǎn)單,就是轉(zhuǎn)啊轉(zhuǎn)地,讓這片雪花用10秒時(shí)間轉(zhuǎn)一圈:
.snowflake {
animation: round 10s linear infinite;
}
@keyframes round {
to {
transform: rotate(1turn);
}
}
知識(shí)點(diǎn):1turn表示一圈
效果如下圖:
(動(dòng)圖太大看不了,可以去文章開(kāi)頭的效果展示提供的網(wǎng)址看哈)
最后,刪除掉輔助助線:
.snowflake {
/* outline: 1px dashed yellow; */
}
效果如下圖:
(動(dòng)圖太大看不了,可以去文章開(kāi)頭的效果展示提供的網(wǎng)址看哈)
大功告成!
四、參考
flex 布局,《CSS3 藝術(shù)》第1.8.1節(jié) 邊框?qū)傩?border,《CSS3 藝術(shù)》第3.1節(jié) 變量 var() 和 表達(dá)式 calc(),《CSS3 藝術(shù)》第7.1節(jié) 變換旋轉(zhuǎn)函數(shù) rotate(),《CSS3 藝術(shù)》第8.1.2節(jié) 變換原點(diǎn) transform-origin,《CSS3 藝術(shù)》第8.2節(jié) 動(dòng)畫(huà) animation,《CSS3 藝術(shù)》第10章
原文出處:https://segmentfault.com/a/1190000021497721
CSS真是神秘~
針對(duì)這個(gè)題目,你的解決方案又是什么呢?
不妨在下面的留言給出,學(xué)習(xí)共勉下~
碼字不易,走過(guò)路過(guò)來(lái)個(gè)贊可否??先謝謝了!
ε=ε=ε=┏(゜ロ゜;)┛
最后
?有疑問(wèn)的同學(xué) 歡迎 評(píng)論區(qū)討論,也歡迎大家加入我的前端技術(shù)交流群 來(lái)討論。搜索《前端陽(yáng)光》公眾號(hào),回復(fù)加群吧!
