iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

https://i.imgur.com/RRxnBPt.jpg

組件實作 : Demo

一、前言

Card 組件通常會出現在像是購物網站的商品資訊,或是影片追劇等電影介紹中,其實只要是文字加上圖片的一個群組,都可以是一張 Card,以下我們要來實作出巴哈姆特動畫瘋【1】的畫面。


二、直接實作一個 Card

圖片來源:https://ani.gamer.com.tw/

圖片來源:https://ani.gamer.com.tw/

2.1 建立一個基本 Card 的 HTML 架構

首先,我們要製作類似上圖的 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>

顯示結果:

https://i.imgur.com/J9b5D1R.jpg

我們用一個 class 為 card 的 div,代表一個完整的卡片,也就是代表一部動畫的資訊,而 card 的組成如下面介紹:

  1. card:一張卡片的所有資訊。
    • card__block:包含封面圖片內的所有資訊(就是不包含底下那排白底黑字的文字content)。
    • card__img:放封面圖片。
  2. time__block:card 內部左上角關於時間的區塊。
    • time__icon:時鐘的 icon(時鐘圖示)。
    • time__text:顯示時間的文字。
  3. card__heart:card 內部右上角的愛心 icon(愛心圖示)。
  4. video__block:card 內部左下角集數區塊。
    • video__icon:影片播放的 icon 圖示(播放圖示)。
    • video__text:顯示集數的文字。
  5. content:card 內部最下排的白色區塊。
    • content__title:動畫名稱。
    • content__item:用來包覆 icon 和 number。
      • content__icon:觀看次數的 icon 圖示(眼睛圖示)。
      • content__number:顯示觀看次數的文字。

2.2 加入圖示

如果你的架構寫好,則會出現類似上面的畫面。若是 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>

2.2 Card 外觀樣式調整

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__blockposition設定為relative,當 CSS 中的position設定為absolute後,愛心、時間以及影片等圖示即可正常的排列 。

顯示結果:

https://i.imgur.com/NcuDK3w.jpg

2.3 圖片區塊加入元素

接著我們要修改時間區塊相關的樣式,使用的程式碼如下。

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;
}

顯示結果:

https://i.imgur.com/Xg3PzDg.jpg

雖然時間圖示沒有到完全的一樣,但也是相當的接近了,我們處理完時間的區塊後,緊接著,我們要修改右上角的愛心圖示。

.fa-heart-o {
	font-size: 1rem;
	font-weight: bold;
	color: #fff;
}

這裡直接修改 Font Awsome 的預設 Class,例如,空心愛心 icon 的 Class 為 fa-heart-o。當我們改完了fa-heart-o之後,愛心的預設顏色由黑色變成白色。

顯示結果:

https://i.imgur.com/edjCoJj.jpg

最後一個元素是集數區塊,我們要將它放在圖片區塊的左下角,程式碼如下。

CSS:

.video__block {
	font-weight: bold;
	margin: 5px;
	color: #fff;
	display: flex;
	align-items: center;
	position: absolute;
	bottom: 0;
}

.video__icon {
	margin-right: 3px;
}

顯示結果:

https://i.imgur.com/HA6UPBx.jpg

2.4 內容區塊調整,自動隱藏文字

到這裡為止,我們已經將圖片區塊的元素排版完成,接下來我們想要把內容區塊做調整,首先我們要使用一個 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;
}

顯示結果:

https://i.imgur.com/1obDkR6.jpg

壞掉啦!動畫名稱的區塊文字太長了,結果被自動換到第二行,所以這個時候我們在content__title裡面加入三行程式碼,用來把過長的文字改用「點點點」來代替。

文字自動隱藏【2】這寫法非常好用,為了方便複製,我將它們寫起來:

	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
  1. overflow: hidden;:超出容器寬度時,隱藏超出範圍。
  2. white-space: nowrap;空白與換行處理,nowrap為不自動換行
  3. 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;
}

顯示結果:

https://i.imgur.com/UWghGUv.jpg

太棒了,我們已經手刻了一個 Card 組件,在下一個章節裡,我們想要加入 RWD 排版,以及動畫名稱的區塊使用跑馬燈的效果,在這之前要先產生 5 個 分Card 組件,讓它們可以有排版的功能。


三、RWD 排版與跑馬燈效果

3.1 加入 5 個 Card 區塊

因為版面會被拉得太長所以我這邊就不先放程式碼,如果有需要的話可以直接去的 Demo 頁面找到完整的程式碼。下面我修改了文字區塊的內容 ,讓它們看起來「稍微」的不一樣。

顯示結果:

https://i.imgur.com/R7qKfwJ.jpg

這裡的寫法不自動隱藏文字!!

3.2 使用 Flexbox 與 Grid 的差別

還記得最外層的 Class 為 container 的 div 嗎?我們要將它當作父層,在這個 container 裡,我們只要使用 flexbox 就能輕鬆的排版,程式碼如下。

CSS:

.container {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}

顯示結果:

https://i.imgur.com/pNAMBrA.jpg

水平置中對齊後⋯又壞掉啦!Flexbox 在做這種排版似乎並沒有那麼的直覺,所以我們決定改用 Grid 來排版,使用的方式如下。

CSS:

.container {
	display: grid;
	grid-template-columns: auto auto;
	gap: 12px;
	padding: 16px 12px 0;
}

顯示結果:

https://i.imgur.com/SEpjmSg.jpg

使用 Grid 可以很輕鬆的製作出格線整齊的版面,grid-template-columns【3】是用來分配欄數,一般我喜歡直接用 auto,幾個 auto 就會有幾欄,手機排版使用兩個 auto。另外,可以使用gap來讓每個 Card 之間都保持 12 px 的間隙,排版更佳美觀。

3.3 RWD 排版

終於進入到了響應式排版的章節,這裡我們會針對手機、平板以及桌機的視窗大小,來做不同的版面配置,程式碼的實作如下。

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 用法即可。

3.4 加入文字跑馬燈

把下面這段程式碼加在 @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%);
	}
}

顯示結果:

https://i.imgur.com/XPuVXvg.gif


四、推薦資源

  1. Cards · Bootstrap v5.0
  2. 80 Card UI Design Inspiration - HTML & CSS Snippets
  3. 76 CSS Cards - Free Frontend
  4. Tailwind CSS Cards - Flowbite
  5. Really Neat CSS Cards For You To Use In Your Website

五、結論

我們完整的切了一個 Card 頁面,製作的過程都類似,善用 position、Flexbox 以及 Grid,就可以做出你想要的版型。若是想要練習 Card 相關的製作,可以參考第四章節的推薦資源,裡面有各種版型可以練習,今天的實作就到這邊結束,謝謝觀看!


六、參考資料

  1. 巴哈姆特動畫瘋
  2. CSS:用 CSS 讓過多的文字自動隱藏
  3. CSS grid-template-columns Property

上一篇
Day 06:Loader 組件實作
下一篇
Day 08:RWD 響應式排版實作
系列文
從零開始手刻網站,30 天打造我的前端武器庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言