昨夜北京下了大雪,讓咱們用 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; */ }
效果以下圖:
大功告成!