組件實作 : Demo
Card 組件通常會出現在像是購物網站的商品資訊,或是影片追劇等電影介紹中,其實只要是文字加上圖片的一個群組,都可以是一張 Card,以下我們要來實作出巴哈姆特動畫瘋【1】的畫面。
圖片來源:https://ani.gamer.com.tw/
首先,我們要製作類似上圖的 Card 組件,在最外圍用一個 container 將包住多個 card 組件。
HTML:
<div class="container">
<!-- card 寫在這裡 -->
~~</div>~~
一個 card 組件會包含下面這些程式碼。
HTML:
<div class="card">
<div class="card__block">
<div class="card__img">
<img src="https://source.unsplash.com/random/400x300?sig=1" />
</div>
<div class="time__block">
<div class="time__icon"><i class="fa fa-clock-o" aria-hidden="true"></i></div>
<div class="time__text">22:00</div>
</div>
<div class="card__heart"><i class="fa fa-heart-o" aria-hidden="true"></i></div>
<div class="video__block">
<div class="video__icon"><i class="fa fa-youtube-play" aria-hidden="true"></i></div>
<div class="video__text">第9集</div>
</div>
</div>
<div class="content">
<div class="content__title">
<div class="marquee__text">OVERLORD</div>
</div>
<div class="contrnt__item">
<div class="content__icon"><i class="fa fa-eye" aria-hidden="true"></i></div>
<div class="content__number">197.1萬</div>
</div>
</div>
</div>
顯示結果:
我們用一個 class 為 card 的 div,代表一個完整的卡片,也就是代表一部動畫的資訊,而 card 的組成如下面介紹:
card
:一張卡片的所有資訊。
card__block
:包含封面圖片內的所有資訊(就是不包含底下那排白底黑字的文字content
)。card__img
:放封面圖片。time__block
:card 內部左上角關於時間的區塊。
time__icon
:時鐘的 icon(時鐘圖示)。time__text
:顯示時間的文字。card__heart
:card 內部右上角的愛心 icon(愛心圖示)。video__block
:card 內部左下角集數區塊。
video__icon
:影片播放的 icon 圖示(播放圖示)。video__text
:顯示集數的文字。content
:card 內部最下排的白色區塊。
content__title
:動畫名稱。content__item
:用來包覆 icon 和 number。
content__icon
:觀看次數的 icon 圖示(眼睛圖示)。content__number
:顯示觀看次數的文字。如果你的架構寫好,則會出現類似上面的畫面。若是 icon 沒有正常顯示,就要加入 Font Awsome 的 CDN。
HTML:(Ver 4.7.0)
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
HTML:(愛心)
<i class="fa fa-heart-o" aria-hidden="true"></i>
HTML:(眼睛)
<i class="fa fa-eye" aria-hidden="true"></i>
HTML:(時鐘)
<i class="fa fa-clock-o" aria-hidden="true"></i>
HTML:(播放)
<i class="fa fa-youtube-play" aria-hidden="true"></i>
CSS 起手式,先讓版面置中。
CSS:
* {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", "Helvetica", "Arial", "PingFangTC-Light",
"STHeitiTC-Light", "Microsoft JhengHei", "微軟正黑體", sans-serif;
}
html {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
我們先參考手機裝置的配置。已知在手機版上,動畫瘋使用 2 欄的版面配置,然後切換到平板則是使用 3 欄的配置,最後在桌機上則是用了 5 欄的配置,我們先對於圖片內部的元素來進行排版,程式碼如下。
CSS:
.card {
border-radius: 3px;
font-size: 14px;
overflow: hidden;
box-shadow: 0 3px 4px rgba(0, 0, 0, 0.1), 0 1px 8px rgba(0, 0, 0, 0.05),
0 2px 20px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.card__block {
position: relative;
overflow: hidden;
}
.card__img {
max-height: 95px;
background-size: cover;
transition: 0.5s;
}
.card__img:hover {
transform: scale(1.5);
transition: 0.5s;
}
.card__heart {
position: absolute;
top: 0;
right: 0;
margin: 5px;
}
.card 是 card 組件的樣式設定,我們在加入一個 box-shadow 當作是最外圍的陰影,為了要讓愛心、時間以及影片讓等內容放在圖片的裡面,我們要在把card__block
的position
設定為relative
,當 CSS 中的position
設定為absolute
後,愛心、時間以及影片等圖示即可正常的排列 。
顯示結果:
接著我們要修改時間區塊相關的樣式,使用的程式碼如下。
CSS:
.time__block {
margin: 5px;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: #fff;
background: rgba(55, 55, 55, 0.9);
display: flex;
position: absolute;
top: 0;
}
.time__icon {
margin-right: 3px;
}
顯示結果:
雖然時間圖示沒有到完全的一樣,但也是相當的接近了,我們處理完時間的區塊後,緊接著,我們要修改右上角的愛心圖示。
.fa-heart-o {
font-size: 1rem;
font-weight: bold;
color: #fff;
}
這裡直接修改 Font Awsome 的預設 Class,例如,空心愛心 icon 的 Class 為 fa-heart-o
。當我們改完了fa-heart-o
之後,愛心的預設顏色由黑色變成白色。
顯示結果:
最後一個元素是集數區塊,我們要將它放在圖片區塊的左下角,程式碼如下。
CSS:
.video__block {
font-weight: bold;
margin: 5px;
color: #fff;
display: flex;
align-items: center;
position: absolute;
bottom: 0;
}
.video__icon {
margin-right: 3px;
}
顯示結果:
到這裡為止,我們已經將圖片區塊的元素排版完成,接下來我們想要把內容區塊做調整,首先我們要使用一個 flexbox 將文字水平排列。
CSS:
.content {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 4px 8px;
vertical-align: middle;
}
.content__icon {
margin: 0 3px;
box-sizing: border-box;
}
.content__title {
max-width: 80px;
}
顯示結果:
壞掉啦!動畫名稱的區塊文字太長了,結果被自動換到第二行,所以這個時候我們在content__title
裡面加入三行程式碼,用來把過長的文字改用「點點點」來代替。
文字自動隱藏【2】這寫法非常好用,為了方便複製,我將它們寫起來:
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
:超出容器寬度時,隱藏超出範圍。white-space: nowrap;
:空白與換行處理,nowrap為不自動換行。text-overflow: ellipsis;
:文字溢出時,使用點點點代替。這邊要注意一點,如果你要使用自動隱藏文字,要把程式碼改寫成下面這樣。
HTML:
<div class="content__title marquee__text">來自深淵 烈日的黃金鄉</div>
因為我們要加入跑馬燈效果,就先不使用自動隱藏文字,不然跑出來結果會是點點點,如果你只是要寫靜態文字就用點點點,若是要用跑馬燈可以不用加上text-overflow: ellipsis;
這句(但是另外兩行還是要加喔,不然會自動換行)。
CSS:
.content {
display: flex;
justify-content: space-around;
align-items: center;
grid-template-columns: auto auto auto;
padding: 4px 8px;
vertical-align: middle;
}
.content__title {
width: 100%;
overflow: hidden;
white-space: nowrap;
}
.contrnt__item {
display: grid;
grid-template-columns: auto auto;
gap: 5px;
align-items: center;
justify-content: center;
}
.content__icon {
width: 100%;
box-sizing: border-box;
}
.content__number {
white-space: nowrap;
}
顯示結果:
太棒了,我們已經手刻了一個 Card 組件,在下一個章節裡,我們想要加入 RWD 排版,以及動畫名稱的區塊使用跑馬燈的效果,在這之前要先產生 5 個 分Card 組件,讓它們可以有排版的功能。
因為版面會被拉得太長所以我這邊就不先放程式碼,如果有需要的話可以直接去的 Demo 頁面找到完整的程式碼。下面我修改了文字區塊的內容 ,讓它們看起來「稍微」的不一樣。
顯示結果:
這裡的寫法不自動隱藏文字!!
還記得最外層的 Class 為 container 的 div 嗎?我們要將它當作父層,在這個 container 裡,我們只要使用 flexbox 就能輕鬆的排版,程式碼如下。
CSS:
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
顯示結果:
水平置中對齊後⋯又壞掉啦!Flexbox 在做這種排版似乎並沒有那麼的直覺,所以我們決定改用 Grid 來排版,使用的方式如下。
CSS:
.container {
display: grid;
grid-template-columns: auto auto;
gap: 12px;
padding: 16px 12px 0;
}
顯示結果:
使用 Grid 可以很輕鬆的製作出格線整齊的版面,grid-template-columns
【3】是用來分配欄數,一般我喜歡直接用 auto,幾個 auto 就會有幾欄,手機排版使用兩個 auto。另外,可以使用gap
來讓每個 Card 之間都保持 12 px 的間隙,排版更佳美觀。
終於進入到了響應式排版的章節,這裡我們會針對手機、平板以及桌機的視窗大小,來做不同的版面配置,程式碼的實作如下。
CSS:
@media (min-width: 575.98px) {
.container {
grid-template-columns: auto auto auto;
gap: 12px;
padding: 16px 12px;
}
.card__img {
max-height: 135px;
}
}
@media (min-width: 1199.98px) {
.container {
grid-template-columns: auto auto auto auto auto;
gap: 12px;
padding: 16px 12px;
}
.card__img {
max-height: 140px;
}
}
575.98 px 為 3 欄的平板排版;1199.98 px 為 5 欄 的桌機排版,grid-template-columns
為 Grid 的用法,此為要平均切割幾欄
的寫法,切好欄位後,再加入 gap 讓 Card 之間有適當的距離。而max-height
是為了要設定成 Card 的高度與巴哈姆特動畫瘋相同,達到像素級還原
的要求。
RWD 的使用會在下一篇中講解,這裡只需要先帶入 Media Queries 用法即可。
把下面這段程式碼加在 @media
的上面,我習慣將 Media Queries 寫在最底下。
CSS:
.marquee__text {
animation: slide 7s linear infinite;
}
.marquee__text:hover {
animation-play-state: paused;
}
@keyframes slide {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
顯示結果:
我們完整的切了一個 Card 頁面,製作的過程都類似,善用 position、Flexbox 以及 Grid,就可以做出你想要的版型。若是想要練習 Card 相關的製作,可以參考第四章節的推薦資源,裡面有各種版型可以練習,今天的實作就到這邊結束,謝謝觀看!