前端每日實戰:170# 二十一世紀二〇年代的第一天,一切剛剛開始………

170.gif

你們好,有一段時間沒有發表《前端每日實戰》做品了,今天,2020年的第一天,終於又從新啓程,我將繼續實踐 PBL(Project-based Learning)的學習方法,並把學習筆記分享出來,和你們交流探討、共同進步。css

這段沒有發表做品的日子裏,我在人民郵電出版社的支持和幫助下,寫出了一本書,命名爲《CSS3 藝術》,它脫胎於《前端每日實戰》的一百多個做品,把僞元素、邊框、背景、陰影、剪切、濾鏡、色彩混合、變量、計數器、變換、緩動、動畫這些概念進行了梳理和總結,但願能爲你們學習 CSS 提供一些幫助。此書已於近日上市,京東、天貓、噹噹都可購買。html

IMG_9685.JPG

接下來進入正題,今天的項目是用純 CSS 製做一個 2020 造型圖案,併爲它增長一點動畫效果。前端

效果預覽

按下右側的「點擊預覽」按鈕能夠在當前頁面預覽,點擊連接能夠全屏預覽。app

https://codepen.io/comehope/pen/jOEGzZxdom

代碼解讀

1、基本的 dom 結構和頁面背景

dom 結構的最外層用 <figure> 元素,表示這是一個圖片:函數

<figure></figure>

頁面用深紅色背景,並採用 grid 佈局:佈局

body {
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: darkred;
}

figure {
    display: grid;
    grid-template-columns: repeat(8, 1em);
    grid-template-rows: repeat(3, 1em);
    font-size: 60px;
    color: whitesmoke;
}

grid 佈局比定位佈局的語義化更好,一樣的佈局效果,grid 佈局的代碼量比定位佈局的代碼量明顯減小。此項目建立了一個 3 行 8 列的網格,爲了能明顯看出網格線,咱們增長一些輔助線,這些輔助線會在做品完成後被刪除掉:學習

figure {
    background-image: 
        linear-gradient(to bottom, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to right, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to top, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to left, transparent 0%, transparent 99%, pink 100%);
    background-size: 1em 1em;
    background-repeat: repeat, repeat, repeat-x, repeat-y;
}

效果以下圖:字體

01.png

2、繪製數字 2

在 dom 中增長有關數字 2 的元素,數字 2 被分紅了 4 部分:flex

<figure>
    <span class="two part1"></span>
    <span class="two part2"></span>
    <span class="two part3"></span>
    <span class="two part4"></span>
</figure>

把這 4 部分分別放置在網格的相應位置上,grid-area 的屬性 x/y 分別表示頂部網格線編號和左側網格線編號,網格線是從 1 開始編號的,以 .part4 爲例,它的頂部網格線是從上數的第3條,左側網格是從左數的第2條,因此它的屬性值是 3/2

.two {
    background-color: currentColor;
}

.two.part1 {grid-area: 1/1;}
.two.part2 {grid-area: 2/2;}
.two.part3 {grid-area: 3/1;}
.two.part4 {grid-area: 3/2;}

效果以下圖:

02.png

接下來把各部分的形狀都改成扇形,border-radius 屬性有 4 個值,分別表明左上、右上、右下、左下的圓角值,以 .part4 爲例,它是左下角爲圓角的扇形,因此它的屬性值是 0 0 0 100%

.two.part1 {grid-area: 1/1; border-radius: 100% 0 0 0;}
.two.part2 {grid-area: 2/2; border-radius: 0 0 100% 0;}
.two.part3 {grid-area: 3/1; border-radius: 100% 0 0 0;}
.two.part4 {grid-area: 3/2; border-radius: 0 0 0 100%;}

效果以下圖:

03.png

這時一個數字 2 已經繪製出來了,另外一個數字 2 不須要增長 dom 元素,只要把第 1 個元素複製一下就能夠了,這裏使用的是 drop-shadow() 函數,它的 2 個參數分別表明複製後的偏移量,此處的參數值爲 4em 0,即水平方向向右平移 4em,垂直方向不變:

.two {
    filter: drop-shadow(4em 0);
}

效果以下圖:

04.png

至此,2個數字 2 就都畫出來了。

3、繪製數字 0

在 dom 中增長有關數字 0 的元素,和數字 2 不一樣,每個數字 0 只須要 1 個 dom 元素,因此 2 個數字 0 須要 2 個 dom 元素:

<figure>
    <span class="two part1"></span>
    <span class="two part2"></span>
    <span class="two part3"></span>
    <span class="two part4"></span>
    <span class="zero copy-1"></span>
    <span class="zero copy-2"></span>
</figure>

在網格中分別定位 2 個數字 0,仍使用 grid-area 參數,但它們的屬性值爲 4 個數字,後 2 個數字分別表明底部網格線編號和右側網格線編號,可知每一個 0 佔據 2 * 2 的網格區域:

.zero.copy-1 {grid-area: 2/3/4/5;}
.zero.copy-2 {grid-area: 2/7/4/9;}

畫出數字 0 的大體輪廓,這裏是利用邊框屬性繪製的,元素自己寬高爲 0,可是有 1em 的邊框,其中上、下邊框是白色,左、右邊框是透明色,注意,在 CSS 中邊框並不必定以線條的形式存在,在此處每條邊框都是三角形:

.zero {
    width: 0;
    height: 0;
    border: 1em solid;
    border-color: currentColor transparent;
}

效果以下圖:

05.png

增長圓角效果:

.zero {
    border-radius: 50%;
}

效果以下圖:

06.png

再傾斜 45 度:

.zero {
    transform: rotate(-45deg);
}

效果以下圖:

07.png

至此,2 個數字 0 也都畫出來了。

4、增長 Happy New Year 文本

在 dom 中增長有關文本的元素,一共 3 個單詞,分別用 3 個元素表示:

<figure>
    <span class="two part1"></span>
    <span class="two part2"></span>
    <span class="two part3"></span>
    <span class="two part4"></span>
    <span class="zero copy-1"></span>
    <span class="zero copy-2"></span>
    <span class="text happy">happy</span>
    <span class="text new">new</span>
    <span class="text year">year</span>
</figure>

效果以下圖,能夠看到這 3 個單詞都重疊在第1行的第2個網格中,這是由於在 grid 佈局下會自動把未指定 grid-area 屬性的元素排放在未被佔用的網格中:

08.png

接下來爲 3 個文本元素設置它們的網格位置:

.text.happy {grid-area: 1/2;}
.text.new {grid-area: 2/4;}
.text.year {grid-area: 1/6;}

效果以下圖:

09.png

接下來設置文字的樣式,把文字都改成大寫字母,加粗,字體用花式字體,爲避免與左側的圖案靠得太緊,再把文字左側增長一點內邊距:

.text {
    text-transform: uppercase;
    font-size: 0.66em;
    line-height: 1.5em;
    font-weight: bold;
    font-family: cursive;
    padding-left: 0.25em;
}

效果以下圖:

10.png

至此,文字繪製完成。

5、增長動畫效果

由於數字 0 造型太抽象,因此咱們讓數字 0 轉動起來,動畫很簡單,就是以 4 秒每圈的速度不斷地轉啊轉,由於數字 0 此前設置了旋轉 45 度,因此動畫的 to 關鍵幀要加上 45 度,另外旋轉的度數是負值,表示逆時針旋轉:

.zero {
    animation: round 4s linear infinite;
}

@keyframes round {
    to {
        transform: rotate(calc(-45deg + -1turn));
    }
}

效果以下圖:

11.gif

不過咱們看到左側的數字 0 在轉動時遮擋住了文字「new」,爲了不遮擋,咱們用色彩混合模式來解決,這樣當數字 0 和文字「new」重疊時,重疊的部分會變爲黑色:

.text {
    mix-blend-mode: difference;
}

效果以下圖:

12.gif

至此,整個做品所有完成了,最後把輔助線刪除掉:

figure {
    /*background-image: 
        linear-gradient(to bottom, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to right, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to top, transparent 0%, transparent 99%, pink 100%),
        linear-gradient(to left, transparent 0%, transparent 99%, pink 100%);
    background-size: 1em 1em;
    background-repeat: repeat, repeat, repeat-x, repeat-y;*/
}

效果以下圖:

13.gif

完整的 CSS 代碼以下:

body {
    margin: 0;![13.gif](/img/bVbCcYh)
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: darkred;
}

figure {
    display: grid;
    grid-template-columns: repeat(8, 1em);
    grid-template-rows: repeat(3, 1em);
    font-size: 60px;
    color: whitesmoke;
}

.two {
    background-color: currentColor;
    filter: drop-shadow(4em 0);
}

.two.part1 {grid-area: 1/1; border-radius: 100% 0 0 0;}
.two.part2 {grid-area: 2/2; border-radius: 0 0 100% 0;}
.two.part3 {grid-area: 3/1; border-radius: 100% 0 0 0;}
.two.part4 {grid-area: 3/2; border-radius: 0 0 0 100%;}

.zero.copy-1 {grid-area: 2/3/4/5;}
.zero.copy-2 {grid-area: 2/7/4/9;}

.zero {
    width: 0;
    height: 0;
    border: 1em solid;
    border-color: currentColor transparent;
    border-radius: 50%;
    transform: rotate(-45deg);
    animation: round 4s linear infinite;
}

@keyframes round {
    to {
        transform: rotate(calc(-45deg + -1turn));
    }
}

.text.happy {grid-area: 1/2;}
.text.new {grid-area: 2/4;}
.text.year {grid-area: 1/6;}

.text {
    text-transform: uppercase;
    font-size: 0.66em;
    line-height: 1.5em;
    font-weight: bold;
    font-family: cursive;
    padding-left: 0.25em;
    mix-blend-mode: difference;
}

參考

  • grid 佈局,《CSS3 藝術》第1.8.2節;
  • drop-shadow() 函數,《CSS3 藝術》第5.2節;
  • border-radius 扇形造型,《CSS3 藝術》第3.3.3節;
  • border-radius 花型造型,《CSS3 藝術》第3.3.5節;
  • animation 動畫,《CSS3 藝術》第10章;
  • mix-blend-mode 色彩混合模式,《CSS3 藝術》第6.3.3節。
相關文章
相關標籤/搜索